Android 探索APP/應用啟動模式、Intent的Flag啟動標志位

寫在前面:Android APP有四種啟動模式——》標準模式(Standard)、棧頂復用模式(SingleTop)、棧內復用模式(SingleTask)、單例模式(SingleInstance),默認就是標準模式。啟動模式決定了Activity在任務棧內的存在方式,影響了Back返回鍵Activity返回的順序。啟動模式看起來簡單,但是實際上想要控制某些Activity的返回順序,需要結合兩個部分一起實現——》一是在AndroidManifest.xml中合理指定Activity的啟動模式;二是在使用Intent啟動Activity時傳入合理的啟動Flag。好,講了這么多其實就是想說APP啟動模式最大的作用是用來控制Activity的返回順序,它由兩部分共同進行控制,控制起來比較復雜,有必要好好學一學,把它搞清楚。

??開始之前我們先來明確一下概念,就是什么是任務棧:
任務棧:一個APP的所有Activity實例是用棧來進行管理的,當我們啟動一個Activity,這個Activity就會入棧處在棧頂,只有在棧頂的Activity是用戶當前可見的,按Back鍵棧頂的Activity就會出棧,如果棧里面還有Activity就繼續顯示棧頂Activity,沒有就直接退出APP,這就是為什么打開的Activity多了需要按多次Back鍵才能退出的原因。
注:1、Home鍵不會導致出棧操作,這也是為什么使用Recent鍵打開最近使用APP能接著之前的Activity頁面使用的原因。2、系統中存在多個任務棧,每個APP存在至少一個任務棧,不同的APP任務棧肯定不一樣。
下面從四種啟動模式開始講解。

一、標準模式(Standard)

??沒在AndroidManifest.xml指定Activity的啟動模式,模式就是標準模式。Standard 是 Android Activity 的默認啟動模式,每次啟動 Activity 時,都會創建一個新的實例,并放入當前任務棧(Task)的頂部。即使該 Activity 已經在任務棧中,也會創建一個新的實例,而不會復用已有實例。
下面畫張圖舉個例子看一下:同一個棧里有Activity1、Activity2,多次啟動Activity1。
在這里插入圖片描述
可以看到每次啟動Actvity1都會重新創建,沒有復用之前的棧內實例。真實的棧可以使用如下adb命令查看:執行命令打印會很多,關注Task display areas in top down Z order:的相關字段即可,比如Task{ec5b36c就是一個已經存在的任務棧。

adb命令:dumpsys activity activitiesTask display areas in top down Z order:TaskDisplayArea DefaultTaskDisplayAreamPreferredTopFocusableRootTask=Task{ec5b36c #115 type=standard A=10158:com.htc.app_launch_mode U=0 visible=true mode=fullscreen translucent=false sz=2}mLastFocusedRootTask=Task{ec5b36c #115 type=standard A=10158:com.htc.app_launch_mode U=0 visible=true mode=fullscreen translucent=false sz=2}Application tokens in top down Z order:* Task{ec5b36c #115 type=standard A=10158:com.htc.app_launch_mode U=0 visible=true mode=fullscreen translucent=false sz=2}bounds=[0,0][1440,3120]* ActivityRecord{ed84d3d u0 com.htc.app_launch_mode/.MainActivity t115}* ActivityRecord{61c5b7d u0 com.htc.app_launch_mode/.MainActivity t115}* Task{6938da2 #1 type=home ?? U=0 visible=false mode=fullscreen translucent=true sz=1}bounds=[0,0][1440,3120]* Task{d8594e9 #112 type=home I=com.google.android.apps.nexuslauncher/.NexusLauncherActivity U=0 rootTaskId=1 visible=false mode=fullscreen translucent=true sz=1}bounds=[0,0][1440,3120]* ActivityRecord{92f632c u0 com.google.android.apps.nexuslauncher/.NexusLauncherActivity t112}

二、棧內復用模式(SingleTask)

??SingleTask 啟動模式意味著:在任務棧(Task)中只會存在一個該 Activity 的實例。如果 Activity 已經存在于任務棧中,則不會重新創建,而是復用已有實例,并調用它的 onNewIntent() 方法。復用時,該 Activity 之上的所有 Activity 都會被清除(類似“回退”操作)。
使用方式直接在AndroidManifest.xml中顯示指定launchMode即可,如下所示:

        <activityandroid:name=".Activity2"android:exported="false"android:launchMode="singleTask"/><activityandroid:name=".MainActivity"android:exported="true"android:launchMode="singleTask"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity>

??假設現在有5個Activity,Activity1、Activity3是棧內復用模式,用下面的圖進行說明:
在這里插入圖片描述

三、棧頂復用模式(SingleTop)

??這種模式的特點是——》如果 Activity 已經在棧頂,則不會新建實例,而是復用當前實例并調用 onNewIntent() 方法。如果 Activity 不在棧頂,則仍會創建新實例。不會清除任務棧中的其他 Activity,與 singleTask 不同。可以用下面這張圖來做一個形象的表示:假設有兩個Activity,Activity1、Activity2都是棧頂模式。
在這里插入圖片描述
可以看到只有在棧頂的會被復用。

四、單例模式(SingleInstance)

??單例模式的特點——》Activity將獨占一個任務棧,且APP所有的任務棧中將只存在一個Activity實例對象。
用下面這張圖舉個例子:假設有三個Activity,Activity1、Activity2是非單例模式,Activity3是單例模式。
在這里插入圖片描述
在這里插入圖片描述
通過上圖可以看到,我們從Activity1開始,但是最終返回的最后一個界面卻變成了Activity3,Activity3再返回就是桌面了,這就是不同的啟動模式對Activity返回順序的影響,如果業務復雜,Activity很多,四種模式混在一起用,要準確控制Activity的返回順序就是一件比較困難的事情了。

五、Intent啟動Activity附帶的Flag

5.1 FLAG_ACTIVITY_NEW_TASK

??這個標志位應該是大家最熟悉的了,如下使用:

Intent intent = new Intent(this, TargetActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

??它最大的特點在于:當 Activity 不是從另一個 Activity 中啟動,而是從 Service、BroadcastReceiver 或 Application 啟動時,必須使用 FLAG_ACTIVITY_NEW_TASK,否則會導致報錯 android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag.因為Service、BroadcastReceiver 或 Application本身是不在任務棧中運行的,不存在任務棧,必須加上FLAG_ACTIVITY_NEW_TASK去新建任務棧。當然了如果APP已經存在了任務棧,那么就不會去創建新的任務棧,而是根據Activity的啟動模式合理復用或者入棧。
注意:FLAG_ACTIVITY_NEW_TASK是APP沒有任務棧的時候去新建,有了的話就不會。
所以啟動Activity都會加上這個Flag,不會有什么副作用,還能防止出錯,屬于萬金油了。示意圖如下:
在這里插入圖片描述

5.2 FLAG_ACTIVITY_CLEAR_TASK

??這個FLAG的意思就是在啟動Activity之前,清空當前啟動它的任務棧,Standard、SingleTask、SingleTop三種模式完全服從FLAG_ACTIVITY_CLEAR_TASK,但是SingleInstance 卻不是這樣,它會影響這個FLAG的行為,具體來說分兩種:1、SingleInstance的Activity啟動其它模式的Activity。2、其它模式的Activity啟動SingleInstance的Activity。使用起來也很簡單:

Intent intent = new Intent(this, TargetActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);

??下面畫一張圖來做個演示:三個Activity,Activity1、Activity3非單例模式,Activity2單例模式。
在這里插入圖片描述
可以看到,Activity1啟動Activity2對應的是非單例模式Activity啟動單例模式Activity:已有任務棧Task1不會被清空,而是新建一個任務棧Task2啟動單例Activity。Activity2啟動Activity3對應單例模式Activity啟動非單例模式Activity:Task2沒有任何影響,Task1中的Activity1被清除,取而代之的是Activity3。

5.3 FLAG_ACTIVITY_MATCH_EXTERNAL

??所有的FLAG沒有寫完,后續會陸續補充完成。

5.4 FLAG_ACTIVITY_SINGLE_TOP

??

5.5 FLAG_ACTIVITY_MULTIPLE_TASK

??

5.6 FLAG_ACTIVITY_FORWARD_RESULT

??

5.7 FLAG_ACTIVITY_FORWARD_RESULT

??

5.8 FLAG_ACTIVITY_PREVIOUS_IS_TOP

??

5.9 FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS

??

5.10 FLAG_ACTIVITY_BROUGHT_TO_FRONT

??

5.11 FLAG_ACTIVITY_RESET_TASK_IF_NEEDED

??

5.12 FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY

??

5.13 FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET

??

5.14 FLAG_ACTIVITY_NEW_DOCUMENT

??

5.15 FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET

??

5.16 FLAG_ACTIVITY_NO_USER_ACTION

??

5.17 FLAG_ACTIVITY_REORDER_TO_FRONT

??

5.18 FLAG_ACTIVITY_NO_ANIMATION

??

5.19 FLAG_ACTIVITY_TASK_ON_HOME

??

5.20 FLAG_ACTIVITY_RETAIN_IN_RECENTS

??

5.21 FLAG_ACTIVITY_LAUNCH_ADJACENT

??

六、總結

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/94437.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/94437.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/94437.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Y9000P部署開源模型

環境信息&#xff1a; 設備&#xff1a;Y9000P GPU&#xff1a;RTX 3060 6G 系統版本&#xff1a;Ubuntu 24.04 一、下載模型 1、環境準備 1、安裝工具 apt-get -y install git-lfs git lfs install apt-get install python3 python-is-python3 pip3.12 config set global.inde…

大模型入門實戰 | 基于 YOLO 數據集微調 Qwen2.5-VL-3B-Instruct 的目標檢測任務

大模型入門實戰 | 基于 YOLO 數據集微調 Qwen2.5-VL-3B-Instruct 的目標檢測任務這篇就是新手向的“保姆級”實操文。你將把 YOLO 檢測數據 轉成 對話式 Grounding 數據&#xff0c;用 ms-swift 做 LoRA 微調&#xff0c;再用腳本 推理 可視化。 但值得注意的是&#xff0c;一…

基于Python+MySQL實現物聯網引論課程一個火警報警及應急處理系統

物聯網引論課程大作業設計報告一、選題、內容及功能說明我們大作業選擇的是題目三&#xff1a;一個火警報警及應急處理系統。主要需要實現四個功能&#xff1a;感知環境溫度&#xff0c;當環境溫度超過閾值&#xff0c;自動觸發報警&#xff1a;終端 led 以固定頻率閃爍&#x…

基于印染數據的可視化系統設計與實現

標題:基于印染數據的可視化系統設計與實現內容:1.摘要 隨著印染行業的快速發展&#xff0c;印染數據呈現爆發式增長。為了更好地管理和分析這些數據&#xff0c;提高印染生產的效率和質量&#xff0c;本研究旨在設計并實現一個基于印染數據的可視化系統。通過收集印染生產過程中…

實驗1 第一個微信小程序

實驗1 第一個微信小程序一、實驗目標二、實驗步驟1. 自動生成小程序2. 手動創建小程序三、程序運行結果四、問題總結與體會chunk的博客地址一、實驗目標 1、學習使用快速啟動模板創建小程序的方法&#xff1b; 2、學習不使用模板手動創建小程序的方法。 二、實驗步驟 1. 自…

(計算機網絡)JWT三部分及 Signature 作用

JWT&#xff08;JSON Web Token&#xff09;是一種用于 無狀態認證 的輕量級令牌&#xff0c;廣泛用于分布式系統、單頁應用&#xff08;SPA&#xff09;和移動端登錄。JWT 結構概覽JWT 由 三部分組成&#xff0c;用 . 分隔&#xff1a;xxxxx.yyyyy.zzzzz Header&#xff08;頭…

LangGraph

LangGraph 是由 LangChain 團隊開發的開源框架&#xff0c;專為構建??復雜、有狀態、多主體&#xff08;Multi-Agent&#xff09;的 LLM 應用??而設計。它通過??圖結構&#xff08;Graph&#xff09;?? 組織工作流&#xff0c;支持循環邏輯、動態分支、狀態持久化和人工…

STM32物聯網項目---ESP8266微信小程序結合OneNET平臺MQTT實現STM32單片機遠程智能控制---MQTT篇(三)

一、前言本篇文章通過發送AT指令&#xff0c;與云平臺建立通訊&#xff1a;1.創建云平臺2.燒錄AT固件3.MQTT訂閱&#xff08;本篇&#xff09;4.單片機代碼編寫5.微信小程序&#xff08;下載微信開發者工具即可使用&#xff09;二、AT指令集介紹AT指令是一種文本序列&#xff0…

Apache Ozone 2.0.0集群部署

單機部署參考&#xff1a;Apache Ozone 介紹與部署使用(最新版2.0.0)-CSDN博客 安裝部署 官方參考&#xff1a;Documentation for Apache Ozone 準備環境 環境準備參考&#xff1a;Linux環境下Hadoop3.4.0集群部署-CSDN博客 1->4-b 參考&#xff1a;Apache Ozone 介紹與部…

【計算機網絡 | 第9篇】信道的極限容量

文章目錄探秘信道的極限容量&#xff1a;從奈氏準則到香農定理一、信道極限容量的基本概念&#x1f914;二、奈氏準則&#xff1a;無噪聲情況下的碼元速率限制&#x1f426;?&#x1f525;&#xff08;一&#xff09;帶寬與信號傳輸的關系&#xff08;二&#xff09;碼間串擾問…

深入理解Linux iptables防火墻:從核心概念到實戰應用

一、概述&#xff1a;什么是iptables&#xff1f; 在Linux系統中&#xff0c;網絡安全防護的核心工具之一便是iptables。它絕非一個簡單的命令&#xff0c;而是一個功能強大的用戶態工具&#xff0c;與Linux內核中的netfilter框架協同工作&#xff0c;共同構建了Linux的防火墻體…

WebRTC音頻QoS方法一.1(NetEQ之音頻網絡延時DelayManager計算補充)

一、整體簡介 NetEQ計算的網絡延時&#xff0c;直接影響變速算法的決策。在變速算法里面啟動關鍵的作用。 網絡延時計算需要考慮兩種情況&#xff1a; 1、單純抖動的網絡延時計算&#xff0c;在UnderrunOptimizer類中實現&#xff1b; 2、在丟包亂序場景下的網絡延時計算。…

實時操作系統FreeRTOS移植到STM32VGT6

一、前言 下載平臺:STM32F407VGT6 代碼使用平臺:VSCode 編譯器:arm-none-aebi-gcc 程序下載工具:STlink 批處理工具:make 移植的FreeRTOS版本:V11.2.0 其實此方法并不局限在arm-none-aebi-gcc中&#xff0c;此方法對于Keil5也是可以使用的&#xff0c; 只不過復制的一些文件不同…

從線到機:AI 與多模態交互如何重塑 B 端與 App 界面設計

當下&#xff0c;界面設計已經不再是單純的“畫屏幕”。AI 的快速發展讓我們不得不重新審視&#xff1a;交互和視覺究竟會走向什么樣的未來&#xff1f;無論是移動端 App&#xff0c;還是復雜的 B 端產品&#xff0c;設計的核心都在于讓界面更懂用戶。本文嘗試從三個角度切入&a…

【智能化解決方案】大模型智能推薦選型系統方案設計

大模型智能推薦選型系統方案設計0 背景1 問題分析與定義2 模型假設與簡化3 核心模型構建3.1 決策變量與參數定義3.2 目標函數3.3 約束條件4 模型求解與驗證4.1 求解策略4.2 驗證方法4.3 模型迭代優化5 方案實施與系統設計5.1 系統架構設計5.2 工作流程5.3 關鍵算法實現5.4 時序…

【Java基礎】HashMap、HashTable與HashSet:區別、聯系與實踐指南

Java中HashMap、HashTable與HashSet的深度解析&#xff1a;區別、聯系與實踐指南 引言 在Java集合框架中&#xff0c;HashMap、HashTable與HashSet是最常用的哈希型數據結構。它們因高效的查找、插入與刪除性能&#xff08;平均時間復雜度O(1)&#xff09;&#xff0c;廣泛應用…

互聯網大廠Java面試實戰:核心技術棧與場景化提問解析(含Spring Boot、微服務、測試框架等)

互聯網大廠Java面試實戰&#xff1a;核心技術棧與場景化提問解析 本文通過模擬面試官與求職者謝飛機的對話&#xff0c;深入探討互聯網大廠Java開發的核心技術棧面試問題&#xff0c;涵蓋Java SE、Spring生態、微服務、大數據等多個領域&#xff0c;結合音視頻、電商、AIGC等業…

人工智能-python-深度學習-參數初始化與損失函數

文章目錄參數初始化與損失函數一、參數初始化1. 固定值初始化1.1 全零初始化1.2 全1初始化1.3 任意常數初始化2. 隨機初始化2.1 均勻分布初始化2.2 正態分布初始化3. Xavier初始化4. He初始化5. 總結二、損失函數1. 線性回歸損失函數1.1 MAE&#xff08;Mean Absolute Error&am…

Android Glide常見問題解決方案:從圖片加載到內存優化

全面總結Glide使用中的典型問題與解決方案&#xff0c;助力提升應用性能與用戶體驗作為Android開發中最流行的圖片加載庫之一&#xff0c;Glide以其簡單易用的API和強大的功能深受開發者喜愛。然而&#xff0c;在實際使用過程中&#xff0c;我們往往會遇到各種問題&#xff0c;…

linux系統ollama監聽0.0.0.0:11434示例

docker應用如dify訪問本地主機部署的ollama&#xff0c;base_url不管配"http://localhost:11434"&#xff0c;還是"http://host_ip:11434"都會報錯。這是因為1&#xff09;docker容器訪問http://localhost:11434&#xff0c;其實訪問的是docker容器自身的服…