Activity相關(guān)

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的作用

  1. FLAG_ACTIVITY_NEW_TASK: 1.如果taskAffinity一致,則會(huì)在當(dāng)前棧打開(kāi),如果不一致,就會(huì)在新的任務(wù)棧打開(kāi)。2.用于Context或者BaseApplication來(lái)startActivity
  2. 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. 生命周期

  1. 正常生命周期:onCreate->onStart(可見(jiàn))->onResume(可交互)->onPause->onStop->onDestroy

  2. 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和onStart

  3. onSaveInstance 和 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)行保存

  4. 對(duì)于在onSaveInstanceState()與onPause()中的數(shù)據(jù)處理有什么區(qū)別?
    onSaveInstanceState用于做一些臨時(shí)狀態(tài)的保存,而onPause用于持久化數(shù)據(jù)的保存

  5. home鍵之后,activity的生命周期是:onPause->onStop->onSaveInstance

4. Activity啟動(dòng)和顯示流程(https://juejin.cn/post/6847902222294990862

  1. Activity.startActivity
  2. Instrumentation.execStartActivity(調(diào)用binder)
  3. ATMS.startActivityAsUser(Android 10之前是AMS)
  4. ActivityStarter(根據(jù)intent等參數(shù)決定如何啟動(dòng)Activity)
  5. ActivityStack(pause上一個(gè)Activity,啟動(dòng)下一個(gè)Activity,包括白屏顯示也是在這里)
  6. ActivityStackSupervisor(判斷啟動(dòng)的Activity對(duì)應(yīng)的進(jìn)程是否啟動(dòng))
    1. 如果進(jìn)程啟動(dòng)了,則調(diào)用ApplicationThread(binder)回到APP,到14
    2. 如果進(jìn)程沒(méi)啟動(dòng),則調(diào)用AMS啟動(dòng)進(jìn)程
  7. 通過(guò)Zygote fork一個(gè)新的進(jìn)程,通過(guò)反射創(chuàng)建ActivityThread
  8. ActivityThread.main創(chuàng)建Looper,創(chuàng)建ActivityThread,啟動(dòng)Looper
  9. ActivityThread.attach關(guān)聯(lián)ApplicationThread和AMS,建立binder通信
  10. AMS(創(chuàng)建和綁定Application)
  11. AMS通過(guò)調(diào)用ApplicationThread這個(gè)binder回到APP
  12. Application通過(guò)mH(handler)回到ActivityThread.handleBindApplication,通過(guò)Instrumentation回調(diào)Application的attachBaseContext和onCreate(初始化ContentProvider也是在這里)
  13. 回到AMS中,啟動(dòng)根Activity
  14. 通過(guò)ActivityStackSupervisor調(diào)用realStartActivityLocked,通過(guò)ApplicationThread binder通信,返回ActivityThread創(chuàng)建Activity

5. Activity和Fragment

  1. 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

  2. 啟動(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:

  1. 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) }

  1. 給Fragment傳參數(shù)的時(shí)候,為什么要用arguments,而不用方法直接調(diào)用呢?
    在修改配置引起的重繪中,如果用arguments系統(tǒng)會(huì)幫忙保存,而直接方法調(diào)用就可能會(huì)丟失

  2. Activity和Fragment之間的通信方式?(參考
    EventBus,Activity,接口回調(diào),ViewModel,Result API

6. 其他

  1. a啟動(dòng)b啟動(dòng)c,b死掉了,怎么把c的result傳回a
    使用FLAG_ACTIVITY_FORWARD_RESULT進(jìn)行參數(shù)傳遞,這個(gè)flag不能和startActivityForResult一起使用

  2. 同時(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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容