1. Activity的啟動(dòng)模式有哪些?
| 屬性 | 描述 | 作用 |
|---|---|---|
| standard | 每啟動(dòng)一個(gè)新的Activity就加入到任務(wù)棧中,并處于棧頂。 | 默認(rèn)啟動(dòng)模式 |
| singleTop | 如果該Activity在任務(wù)棧的棧頂,那么就不會(huì)創(chuàng)建新的Activity,而是復(fù)用該Activity,并走onNewIntent的回調(diào)。如果不在棧頂,則創(chuàng)建新的實(shí)例 | 1. 通知欄跳轉(zhuǎn)當(dāng)前Activity 2. Activity自己跳轉(zhuǎn)自己 |
| singleTask | 如果當(dāng)前的任務(wù)棧中有該Activity,則會(huì)把該實(shí)例上面的Activity退棧,并走onNewIntent的回調(diào)。如果不在當(dāng)前棧,則創(chuàng)建新的實(shí)例 | 作為應(yīng)用首頁(yè)跳轉(zhuǎn) |
| singleInstance | 創(chuàng)建新的任務(wù)棧管理該活動(dòng),且棧中只會(huì)存在該Activity實(shí)例 ,如果該實(shí)例存在則直接復(fù)用,并走onNewIntent的回調(diào),否則創(chuàng)建 | 作為獨(dú)立的頁(yè)面給其他應(yīng)用調(diào)用或者跳轉(zhuǎn),不會(huì)影響自己的任務(wù)棧和其他應(yīng)用的任務(wù)棧 |
P.S. 對(duì)于singleInstance來(lái)說(shuō),如果是調(diào)用startActivityForResult,會(huì)在當(dāng)前棧打開(kāi)新的Activity,如果是startActivity會(huì)在其他棧打開(kāi)
2. Flag的作用
- FLAG_ACTIVITY_NEW_TASK: 1.如果taskAffinity一致,則會(huì)在當(dāng)前棧打開(kāi),如果不一致,就會(huì)在新的任務(wù)棧打開(kāi)。2.用于Context或者BaseApplication來(lái)startActivity
- FLAG_ACTIVITY_CLEAR_TASK:需要與FLAG_ACTIVITY_NEW_TASK結(jié)合使用,清除當(dāng)前任務(wù)棧,然后打開(kāi)新的Activity
3.FLAG_ACTIVITY_SINGLE_TOP:與singleTop效果一致
4.FLAG_ACTIVITY_CLEAR_TOP:與singleTask效果類(lèi)似,但是不會(huì)走onNewIntent回調(diào)
3. taskAffinity(親和性)
設(shè)置activity和任務(wù)棧的依附關(guān)系
每個(gè)Activity可以設(shè)置不同的taskAffinity,如果沒(méi)有設(shè)置默認(rèn)等于Application的taskAffinity,如果Application沒(méi)有設(shè)置,則默認(rèn)等于包名
需要配合其他屬性使用才會(huì)生效
+singleTask(FLAG_ACTIVITY_NEW_TASK)會(huì)創(chuàng)建新的任務(wù)棧
+allowTaskReparenting = true 當(dāng)其他應(yīng)用打開(kāi)該Activity時(shí),Activity會(huì)默認(rèn)在應(yīng)用的任務(wù)棧中,如果有相同的taskAffinity的任務(wù)棧到前臺(tái)后,該Activity會(huì)遷移到該任務(wù)棧中。默認(rèn)為false,不會(huì)遷移。
如果是不同的taskAffinity的,幾時(shí)同一個(gè)應(yīng)用也會(huì)出現(xiàn)多個(gè)任務(wù)棧在最近任務(wù)欄中
4. 生命周期
正常生命周期:onCreate->onStart(可見(jiàn))->onResume(可交互)->onPause->onStop->onDestroy
Activity A啟動(dòng)Activity B生命周期是怎么走?
A.onPause->B.onCreate->B.onStart->B.onResume->A.onStop->B.onPause->A.onRestart->A.onStart->A.onResume->B.onStop->B.onDestory
2.1. 如果B是透明的Activity或者是DialogActivity 會(huì)有什么區(qū)別:A不會(huì)執(zhí)行onStop, onRestart和onStartonSaveInstance 和 onRestoreInstance
2.1. onSaveInstance
回調(diào)時(shí)機(jī):onPause->onStop->onSaveInstance
觸發(fā)情景:1.HOME鍵 2.關(guān)閉屏幕 3.打開(kāi)其他Activity 4.切換方向
2.2. onRestoreInstance
回調(diào)時(shí)機(jī):onCreate->onStart->onRestoreInstance->onResume
觸發(fā)情景:只有重建Activity之后才會(huì)調(diào)用
2.3. 原理:將每一個(gè)有ID的View,以它的ID為Key,狀態(tài)為Value存儲(chǔ)在一個(gè)哈希數(shù)組中,進(jìn)行保存對(duì)于在onSaveInstanceState()與onPause()中的數(shù)據(jù)處理有什么區(qū)別?
onSaveInstanceState用于做一些臨時(shí)狀態(tài)的保存,而onPause用于持久化數(shù)據(jù)的保存home鍵之后,activity的生命周期是:onPause->onStop->onSaveInstance
4. Activity啟動(dòng)和顯示流程(https://juejin.cn/post/6847902222294990862)
- Activity.startActivity
- Instrumentation.execStartActivity(調(diào)用binder)
- ATMS.startActivityAsUser(Android 10之前是AMS)
- ActivityStarter(根據(jù)intent等參數(shù)決定如何啟動(dòng)Activity)
- ActivityStack(pause上一個(gè)Activity,啟動(dòng)下一個(gè)Activity,包括白屏顯示也是在這里)
- ActivityStackSupervisor(判斷啟動(dòng)的Activity對(duì)應(yīng)的進(jìn)程是否啟動(dòng))
- 如果進(jìn)程啟動(dòng)了,則調(diào)用ApplicationThread(binder)回到APP,到14
- 如果進(jìn)程沒(méi)啟動(dòng),則調(diào)用AMS啟動(dòng)進(jìn)程
- 通過(guò)Zygote fork一個(gè)新的進(jìn)程,通過(guò)反射創(chuàng)建ActivityThread
- ActivityThread.main創(chuàng)建Looper,創(chuàng)建ActivityThread,啟動(dòng)Looper
- ActivityThread.attach關(guān)聯(lián)ApplicationThread和AMS,建立binder通信
- AMS(創(chuàng)建和綁定Application)
- AMS通過(guò)調(diào)用ApplicationThread這個(gè)binder回到APP
- Application通過(guò)mH(handler)回到ActivityThread.handleBindApplication,通過(guò)Instrumentation回調(diào)Application的attachBaseContext和onCreate(初始化ContentProvider也是在這里)
- 回到AMS中,啟動(dòng)根Activity
- 通過(guò)ActivityStackSupervisor調(diào)用realStartActivityLocked,通過(guò)ApplicationThread binder通信,返回ActivityThread創(chuàng)建Activity
5. Activity和Fragment
Fragment生命周期:
onAttach -> onCreate -> onCreateView -> onViewCreated -> onStart -> onResume -> onPause -> onStop -> onDestoryView -> onDestroy -> onDetach
onAttach: 當(dāng)Fragment和Activity建立聯(lián)系時(shí)回調(diào)
onCreateView: Fragment創(chuàng)建視圖
onViewCreated: 在onCreateView之后調(diào)用,用于給子類(lèi)創(chuàng)建自己獨(dú)特的View
onDestroyView: Fragment銷(xiāo)毀視圖,與onCreateView相對(duì)應(yīng)
onDetach: 當(dāng)Fragment和Activity解除綁定
P.S.在replace或者是ViewPager中,如果Fragment視圖被銷(xiāo)毀一定會(huì)走onDestroyView,但是不一定會(huì)走onDestroy啟動(dòng)一個(gè)帶有Fragment的Activity,他們的生命周期是怎樣的?(參考)
調(diào)用順序:
D/MainActivity: MainActivity:
D/MainActivity: onCreate: start
D/MainFragment: onAttach:
D/MainFragment: onCreate:
D/MainActivity: onCreate: end
D/MainFragment: onCreateView:
D/MainFragment: onViewCreated:
D/MainFragment: onActivityCreated:
D/MainFragment: onViewStateRestored:
D/MainFragment: onCreateAnimation:
D/MainFragment: onCreateAnimator:
D/MainFragment: onStart:
D/MainActivity: onStart:
D/MainActivity: onResume:
D/MainFragment: onResume:
- activity和fragment startActivityForResult有什么區(qū)別
androidx.fragment:1.3之后
Fragment.startActivityForResult
->FragmentManager.launchStartActivityForResult
->ActivityResultLauncher.launch(Fragment的requestCode在這里做了一個(gè)轉(zhuǎn)換,使用的是Fragment獨(dú)特的key去請(qǐng)求Activity,在Fragment的onActivityResult中再去做還原。而Fragment的requestCode在Activity的onActivityResult中requestCode是一樣的。)
androidx.fragment:1.3之前
Fragment.startActivityForResult
->FragmentHostCallback.onStartActivityFromFragment
->FragmentActivity.startActivityFromFragment(在這里對(duì)Fragment的requestCode做編碼運(yùn)算,讓它大于0xffff0000。之后在Fragment的onActivityResult中再去做還原。而Fragment的requestCode在Activity的onActivityResult中是編碼后的requestCode。)
onActivityResult回調(diào)
啟動(dòng)Activity之后,會(huì)在ActivityThread啟動(dòng)dispatchActivityResult,這個(gè)會(huì)優(yōu)先回到當(dāng)前的Activity,然后執(zhí)行它的super,然后到fragment
1.3之前通過(guò)FragmentController找到對(duì)應(yīng)的fragment
1.3之后通過(guò)mActivityResultRegistry進(jìn)行dispatchResult
startActivityForResult新方式:Activity/Fragment.registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { onActivityResult(it) }
給Fragment傳參數(shù)的時(shí)候,為什么要用arguments,而不用方法直接調(diào)用呢?
在修改配置引起的重繪中,如果用arguments系統(tǒng)會(huì)幫忙保存,而直接方法調(diào)用就可能會(huì)丟失Activity和Fragment之間的通信方式?(參考)
EventBus,Activity,接口回調(diào),ViewModel,Result API
6. 其他
a啟動(dòng)b啟動(dòng)c,b死掉了,怎么把c的result傳回a
使用FLAG_ACTIVITY_FORWARD_RESULT進(jìn)行參數(shù)傳遞,這個(gè)flag不能和startActivityForResult一起使用同時(shí)啟動(dòng)兩個(gè)Activity,
TaskStackBuilder.startActivitys(Intent [] intents)
3.activity和application的context,startactivity有什么區(qū)別?
如果 Context is not an Activity,則通過(guò) Context.startActivity()的時(shí)候,必須加上一個(gè) Intent.FLAG_ACTIVITY_NEW_TASK標(biāo)志。因?yàn)榉?Activity環(huán)境啟動(dòng)Activity 的時(shí)候沒(méi)有 Activity 棧,所以需要加上這個(gè)標(biāo)志位新建一個(gè)棧。
另,application的context生命周期是整個(gè)應(yīng)用的生命周期,activity的生命周期只是activity