通過實例解析android Activity啟動過程
注:只是說明啟動activity的過程(ActivityThread如何與ActivityManagerService簡稱AmS進行進程間通信調(diào)用全過程),不解析android從zygote(受精卵)到整個系統(tǒng)服務的啟動
具體來講,啟動activity的方式有以下幾種:
- 在應用程序中startActivity()或startActivityForResult()方法啟動指定activity
- 在HOME(桌面)程序中單擊應用圖標,啟動新的activity
- 按"BACK"鍵結(jié)束當前activity,自動啟動上一個activity
- 長按“Home”鍵,顯示出當前任務列表,從中選擇一個啟動。
先分析第2種方式
android的HOMe桌面程序(launcher)是android系統(tǒng)啟動的第一個應用程序,其他的應用程序安裝后,會在launcher上創(chuàng)建一個快捷圖標,我們點擊桌面上的快捷圖標就會啟動相應的app
桌面程序Launcher.java(源碼基于4.2.2,我沒有下載4.2.2,參考網(wǎng)上源碼)
在android4.0\packages\apps\Launcher2\src\com\android\launcher2
當點擊一個應用圖標時會執(zhí)行一連串流程
-》Launcher.onClick(View v)單擊app圖標
-》Launcher.startActivitySafely(v,intent,tag)這里比4.0多的一個參數(shù),可能性能優(yōu)化吧
-》Launcher.startActivity(v, intent,tag)
-》Activity.startActivity(intent,opts.toBundle())
-》Activity.startActivityForResult(intent,-1,options);
到這里直接跳轉(zhuǎn)到第一個問題上來了(直接分析第一個就可以解決第二個)
第4種方式---長按“Home”鍵,顯示出當前任務列表,從中選擇一個啟動
流程:
public static final int KEYCODE_HOME = 3; PhoneWindowManager.interceptKeyBeforeDispatching()處理長按home事件 showRecentAppsDialog();//彈出近期任務的對話框 RecentApplicationsDialog.onclick.getContext().startActivity(intent);//到這里流程就相同了
這個調(diào)用的其實也是第1種的startActivity()。所以1,2,4可以用相同處理流程解析,在后面接紹第1中方式處理流程-----fly
第3種方式(原理與第1種大致相同)
假設(shè)一個app,ActivityA啟動ActivityB,然后ActivityB按下"BACK"鍵其實執(zhí)行的是activity的finish()方法
簡單流程:
ActivityB.finish()
Activity.finish()
ActivityManagerNative.getDefault().finishActivity()
ActivityManagerService.finishActivity()
ActivityStack.requestFinishActivityLocked()
ActivityStack.finishActivityLocked()
ActivityStack.startPausingLocked()
ActivityB向AmS發(fā)送finish()請求
// If the activity is PAUSING, we will complete the finish once
// it is done pausing; else we can just directly finish it here.
上面解釋。AmS會先會在ActivityStack.finishActivityLocked()方法中檢查我們要finish的activity的狀態(tài)是否處于pause狀態(tài),如果是將直接執(zhí)行finish操作,否則,必須先執(zhí)行startPausingLocked()---這里終點是resume恢復上一個ActivityA,將A顯示在前臺窗口
IApplicationThread.schedulePauseActivity()
ActivityThread.schedulePauseActivity()
ActivityThread.sendMessage()
ActivityThread.H.sendMessage()
ActivityThread.H.handleMessage()
ActivityThread.handlePauseActivity()
ActivityThread.performPauseActivity()
Instrumentation.callActivityOnPause()
Activity.performPause()
Activity.onPause()
ActivityManagerNative.getDefault().activityPaused()
ActivityManagerService.activityPaused()
ActivityStack.activityPausedLocked()
ActivityStack.completePauseLocked()
接上面,AmS通知當前ActivityB進入Paused狀態(tài),當ActivityB進入paused狀態(tài)后即Activity.onPause()方法執(zhí)行完后,通知AmS我已經(jīng)執(zhí)行完pause操作。于是AmS就準備要在ActivityB所在的進程和任務中恢復ActivityA了;
ActivityStack.resumeTopActivityLocked()
ActivityStack.resumeTopInnerLocked()
IApplicationThread.scheduleResumeActivity()
ActivityThread.scheduleResumeActivity()
ActivityThread.sendMessage()
ActivityTherad.H.sendMessage()
ActivityThread.H.handleMessage()
ActivityThread.H.handleResumeActivity()
Activity.performResume()
Activity.performRestart()
Instrumentation.callActivityOnRestart()
Activity.onRestart()
Activity.performStart()
Instrumentation.callActivityOnStart()
Activity.onStart()
Instrumentation.callActivityOnResume()
Activity.onResume()
到這里activityA已經(jīng)啟動起來了,但是ActivityB還沒有被finish掉,在ActivityThread.H.handleResumeActivity中會
調(diào)用Looper.myQueue().addIdleHandler(new Idler()) 這個方法實現(xiàn)ActivityB的最終銷毀操作
Looper.myQueue().addIdleHandler(new Idler())
ActivityManagerNative.getDefault().activityIdle()
ActivityManagerService.activityIdle()
ActivityStackSupervisor.activityIdleInternalLocked()
ActivityStack.destroyActivityLocked()
IApplicationThread.scheduleDestoryActivity()
ActivityThread.scheduleDestoryActivity()
ActivityThread.sendMessage()
ActivityThread.H.sendMessage()
ActivityThread.H.handleMessage()
ActivityThread.handleDestoryActivity()
ActivityThread.performDestoryActivity()
Activity.performStop()
Instrumentation.callActivityOnStop()
Activity.onStop()
Instrumentation.callActivityOnDestory()
Activity.performDestory()
Acitivity.onDestory()
ActivityManagerNative.getDefault().activityDestoryed()
ActivityManagerService.activityDestoryed()
ActivityStack.activityDestoryedLocked()
這就是finish()的全部流程了(具體與WindowsManagerService的交互以后再補充)
第1種方式--ActivityA啟動ActivityB為例
從startActivity()開始分析。
簡單流程(有時間完整過一遍源碼)
Activity.startActivity
Activity.startActivityForResult
Instrumentation.execStartActivity
ActivityManagerProxy.startActivity
ActivityManagerService.startActivity
ActivityStack.startActivityMayWait
ActivityStack.startActivityLocked
ActivityStack.startActivityUncheckedLocked
ActivityStack.resumeTopActivityLocked
ActivityStack.startPausingLocked
ApplicationThreadProxy.schedulePauseActivity
ApplicationThread.schedulePauseActivity
ActivityThread.queueOrSendMessage
H.handleMessage
ActivityThread.handlePauseActivity
ActivityManagerProxy.activityPaused
ActivityManagerService.activityPaused
ActivityStack.activityPaused
ActivityStack.completePauseLocked
ActivityStack.resumeTopActivityLokced
ActivityStack.startSpecificActivityLocked
ActivityStack.realStartActivityLocked
ApplicationThreadProxy.scheduleLaunchActivity
ApplicationThread.scheduleLaunchActivity
ActivityThread.queueOrSendMessage
H.handleMessage
ActivityThread.handleLaunchActivity
ActivityThread.performLaunchActivity
AcitiviyB.onCreate
要查看ActivityManagerNative.java,ActivityManagerProxy.java,ActivityManagerService,還有binder關(guān)系看一張圖就可以了
從圖中可以看出代理類:使用ActivityManagerProxy代理類,來代理ActivityManagerNative類的子類ActivityManagerService;
所以執(zhí)行請求都是傳遞到ActivityManagerService進行處理
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android開發(fā)中自定義ProgressBar控件的方法示例
這篇文章主要介紹了Android開發(fā)中自定義ProgressBar控件的方法,結(jié)合實例形式分析了自定義ProgressBar控件的定義與使用方法,需要的朋友可以參考下2017-10-10Android TextView 去掉自適應默認的fontpadding的實現(xiàn)方法
這篇文章主要介紹了Android TextView 去掉自適應默認的fontpadding的實現(xiàn)方法的相關(guān)資料,希望通過本文大家能夠掌握這部分內(nèi)容,需要的朋友可以參考下2017-09-09Android實現(xiàn)自動變換大小的ViewPager
ViewPager使用適配器類將數(shù)據(jù)和view的處理分離,ViewPager的適配器叫PagerAdapter,這是一個抽象類,不能實例化,所以它有兩個子類:FragmentPagerAdapter 和 FragmentStatePagerAdapter,這兩個都是處理頁面為Fragment的情況2022-11-11Android 動畫之RotateAnimation應用詳解
本節(jié)講解旋轉(zhuǎn)動畫效果RotateAnimation方法的應用,有需要的朋友可以參考下2012-12-12Android NDK生成及連接靜態(tài)庫與動態(tài)庫的方法
這篇文章主要介紹了Android NDK生成及連接靜態(tài)庫與動態(tài)庫的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-08-08Crashlytics Android 異常報告統(tǒng)計管理(詳解)
下面小編就為大家?guī)硪黄狢rashlytics Android 異常報告統(tǒng)計管理(詳解)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-05-05