一、Instrumentation類 : 該類是一個工具類,ActivityThread接收到AMS的指令建立和排程互動都由它來執行
ActivityThread的構造方法很簡單就是建立了一個ResourcesManager對象,用于管理應用程式中的資源檔案
Application環境與framework-res.apk構成了Android程式的運作環境,通過Context應用程式的大管家,可以調用程序所用到的資源和方法。
二、AMS服務的啟動過程
1.SystemServer.java的
main()
public static void main(String[] args) {
new SystemServer().run(); }
2. SystemServer.java的
run()
private void run() {
...
System.loadLibrary("android_servers");//1
...
mSystemServiceManager = new SystemServiceManager(mSystemContext);//2
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
...
try {
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartServices");
startBootstrapServices();//3 ---------------->引導服務
startCoreServices();//4 ---------------->核心服務
startOtherServices();//5 ---------------->其他服務
}
3.SystemServer.java的
startBootstrapServices
()
private void startBootstrapServices() {
// Activity manager runs the show.
mActivityManagerService = mSystemServiceManager.startService( ActivityManagerService.Lifecycle.class).getService();
我們知道SystemServiceManager的startService方法最終會傳回Lifecycle類型的對象,緊接着又調用了Lifecycle的getService方法,這個方法會傳回AMS類型的mService對象
mActivityManagerService.setSystemProcess();
……
mActivityManagerService.installSystemProviders();
……
mActivityManagerService.systemReady(new Runnable() {
@Override public void run() {
Slog.i(TAG, "Making services ready");
mSystemServiceManager.startBootPhase( SystemService.PHASE_ACTIVITY_MANAGER_READY);
try { mActivityManagerService.startObservingNativeCrashes();
4.
Lifecycle
類的介紹
public static final class Lifecycle extends SystemService {
private final ActivityManagerService mService;
public Lifecycle(Context context) {
super(context);
mService = new ActivityManagerService(context);
}
@Override
public void onStart() {
mService.start();
}
@Override
public void onCleanupUser(int userId) {
mService.mBatteryStatsService.onCleanupUser(userId);
}
public ActivityManagerService getService() {
return mService;
}
}
5.AMS的構造方法
public ActivityManagerService(Context systemContext) {
//獲得系統的ActivityThread
mSystemThread = ActivityThread.currentActivityThread();
//建立一個HandlerThread用來處理AMS接收的指令
mHandlerThread = new ServiceThread(TAG, android.os.Process.THREAD_PRIORITY_FOREGROUND, false );
mHandlerThread.start();
mHandler = new MainHandler(mHandlerThread.getLooper());
mUiHandler = new UiHandler();
//初始化廣播的隊列
mFgBroadcastQueue = new BroadcastQueue(this, mHandler, "foreground", BROADCAST_FG_TIMEOUT, false);
mBgBroadcastQueue = new BroadcastQueue(this, mHandler, "background", BROADCAST_BG_TIMEOUT, true);
mBroadcastQueues[
6.AMS的方法systemReady
1:在systemReady的時候初始化了deviceIdleController等對象
2:移除并殺死了那些不該在AMS之前啟動的程序
3:執行了參數傳入的回調函數
4:啟動了Launcer界面和SystemUI
5:啟動那些persistent配置為1的程序。
總結:AMS服務啟動主要分為幾個步驟 小米視訊增加組内自動化測試
1. 建立了SystemServer程序的運作環境,包括一個ActivityThread主線程,一個和系統程序相關的Context對象。
2. 調用AMS的構造方法和start方法,對AMS必要的内容進行初始化
3. 将函數AMS注冊到ServiceManager中,同時對systemServer程序也建立了一個ProcessRecord對象,并設定Context的appliation為framework-res的application對象
4. 将settingsProvider加載到系統程序systemServer中
5. 調用systemReady方法做一些啟動前的就緒工作,并啟動了HomeActivity和SystemUI 三、Activity的啟動流程 1.Activity的
startActivity
()
public void startActivity(Intent intent, @Nullable Bundle options) {
if (options != null) {
startActivityForResult(intent, -
.ActivityResult ar = mInstrumentation.execStartActivity( this, mMainThread.getApplicationThread(), mToken, who, intent, requestCode, options); (whoThread, who.getBasePackageName(), intent, intent.resolveTypeIfNeeded(who.getContentResolver()), token, target != null ? target.mEmbeddedID : null, requestCode, 5. (caller, - 類,主要管理Task和Stack 6.ActivityStarter的startActivityMayWait () : 根據Intent從PMS中查詢目标Activity的資訊
final int startActivityMayWait(.....){
//PMS服務根據intent查詢要啟動的Activity B的資訊,儲存到ActivityInfo中
intent = new Intent(intent);
ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags, profilerInfo, userId);
……
//決定目前活動的stack
ActivityContainer container = (ActivityContainer)iContainer;
//将PMS中查詢到的Activity B的資訊當做參數
int res = startActivity(caller, intent, resolvedType, aInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity, componentSpecified, null, container, inTask);
7.ActivityStarter的
startActivity() : 在AMS中找調用程序的processRecord資訊,調用Activity的ActivityRecord資訊,目标Activity還沒有啟動,是以需要先建立一個目标Activity的ActivityRecord資訊
final int startActivityLocked(
......){
//即調用者的Activity元件
ActivityRecord sourceRecord = null;
//傳回結果的Activity元件
ActivityRecord resultRecord = null;
if (resultTo != null) {
//根據resultTo Binder對象得到其指向的ActivityRecord,即Activity A的ActivityRecord資訊
sourceRecord = isInAnyStackLocked(resultTo);
//一般情況下請求的Activity和要接收傳回結果的Activity是同一個
if (sourceRecord != null) {
if (requestCode >=
(mService, callerApp, callingUid, callingPackage, intent, resolvedType, aInfo, mService.mConfiguration, resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null, this, container, options); )方法來啟動 )
對象,根據參數傳進來的代表Activity A的binder對象,來獲得Activity A的ActivityRecord資訊。 然後擷取調用程序的pid和調用程式的uid,根據這些資訊和ainfo建立一個ActivityRecord對象r,代表ActivityB。
這樣就擷取了調用者的Activity A的元件資訊,和即将要啟動的目标Activity B的資訊。 分别儲存在 sourceRecord和r中,最後調用startActivityUncheckedLocked方法來繼續啟動Activity B 9. ActivityStarter的startActivityUnchecked的函數 : 主要來處理啟動模式相關的邏輯,根據不同的啟動模式,找到相應的對的Task,然後又相應的Task進行處理 ........ setInitialState(r, options, inTask, doResume, startFlags, sourceRecord, voiceSession,voiceInteractor); 處理
Activity的四種不同的啟動模式 預設為standard模式
....... if (dontStart) {
if (mDoResume) { //make sure we have correctly resumed the top activity 確定目前的activity的棧頂
mSupervisor.resumeFocusedStackTopActivityLocked();}
10.ActivityStackSupervisor的resumeFocusedStackTopActivityLocked() 11.ActivityStack的resumeTopActivityInnerLocked() 12.ActivityStackSupervisor的startSpecificActivityLocked() 13.ActivityStackSupervisor的pauseBackStacks(....) : 暫停所有堆棧中的所有活動,或者隻暫停後面的堆棧 someActivityPaused |= stack.startPausingLocked(userLeaving, false, resuming,dontWait);
ActivityStack有三個成員變量,mResumedActivity表示這個棧中處于激活狀态的Activity。這個棧中處于激活狀态的Acticity就是Acticity A了。
mLastPausedActivity表示上一次被暫停的Activity。
mLastPausingActivity即目前棧中正在被暫停的Activity。
mResumedActivity表示Activity A不是Null,是以調用startPasingLocked來暫停Activity A
Activity啟動流程的第一部分就到此為止。總結下這部分做的主要工作
- 調用Activity的startActivity方法來啟動目标Activity
- 調用Instrumentation的方法execStartActivity方法,友善Instrumentation對互動進行監測
- 以上部分是在App1的程序中執行,之後會通過程序間通信調用到AMS服務中調用AMS的startActivity方法。此時進入SystemServer程序。
- 然後由AMS中管理Acticity核心排程的類ActivityStackSupervisor的方法startActivityMayWait來處理。該方法中主要是根據Intent從PMS中查詢目标Activity的資訊
- ActivityStackSuperVisor的startActivityLocked方法主要是在AMS中找調用程序的processRecord資訊,調用Activity的ActivityRecord資訊,目标Activity還沒有啟動,是以需要先建立一個目标Activity的ActivityRecord資訊。
- ActivityStackSuperVisor的StartActivityUncheckedLocked方法主要來處理啟動模式相關的邏輯,根據不同的啟動模式,找到相應的對的Task,然後又相應的Task進行處理
- ActivityStack将目标Activity加入到對應的Task頂部
- 調用ActivityStackSuperVisor的resumeTopActivityLocked方法找到處于前台的Stack,然後調用它的resumeTopActivityLocked方法激活目标Activity.
- 目前的Stack的棧開始Pasuing調用的Activity
三、暫停ActivityA的流程
final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, boolean resuming, boolean dontWait) {
//mResumeActivity代表目前激活的Activity,即Activity A
ActivityRecord prev = mResumedActivity;
……
//目前處于激活狀态mResumedActivity 的設定為null
mResumedActivity = null;
//即将要處于pasuing狀态的Activity 就是Activity A
mPausingActivity = prev;
mLastPausedActivity = prev;
……
try {
prev.shortComponentName, "userLeaving=" + userLeaving);
mService.updateUsageStats(prev, false);
mService.getLifecycleManager().scheduleTransaction(prev.app.thread, prev.appToken,PauseActivityItem.obtain(prev.finishing, userLeaving,
prev.configChangeFlags, pauseImmediately));
2. AMS的activityPaused
public final void activityPaused(IBinder token) {
//獲或Activity 所在的ActivityStack
ActivityStack stack = ActivityRecord.getStackLocked(token);
if (stack != null) {
//調用目标ActivityStack的activityPauseLocked方法
stack.activityPausedLocked(token, false); } }
3. ActivityStack 的activityPauseLocked
final void activityPausedLocked(IBinder token, boolean timeout) {
//根據token擷取Activity A的ActivityRecord對象
final ActivityRecord r = isInStackLocked(token);
if (r != null) {
//移除pause逾時消息
mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
if (mPausingActivity == r) {
//調用completePauseLocked方法繼續執行pause邏輯
completePauseLocked(true); } ……
注解:Token代表的是Activity的binder對象,根據token可以獲得Activity A的資訊ActivityRecord,移除Pause逾時消息,
當執行完pause邏輯的ActivityRecord和我們執行pause邏輯前的activityRecord一樣的時候,即是同一個Activity,
就可以調用completePauseLocked方法來完成Activity A Pause最後的邏輯了。
四、啟動一個新的Activity B 1. ActivityStackSuperVisor 的
startSpecificActivityLocked : 開啟一個新的Activity
void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
//擷取目标Activity的程序ProcessRecord
ProcessRecord app = mService.getProcessRecordLocked(r.processName, r.info.applicationInfo.uid, true);
……
//,由于目标Activity所在程序還沒有建立,是以為空
if (app != null && app.thread != null) {
…… }
mService.startProcessLocked(r.processName, r.info.applicationInfo, true,
2. AMS.的startProcessLocked
final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, ……) {
long startTime = SystemClock.elapsedRealtime();
ProcessRecord app; if (!isolated) {
app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
String hostingNameStr = hostingName != null ? hostingName.flattenToShortString() : null;
……
startProcessLocked( app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3. AMS的startProcessLocked private boolean startProcessLocked(String hostingType, String hostingNameStr, String entryPoint,ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
String seInfo, String requiredAbi, String instructionSet, String invokeWith,long startTime) {
.....
final ProcessStartResult startResult = startProcess(app.hostingType, entryPoint,app, app.startUid, gids, runtimeFlags, mountExternal, app.seInfo,requiredAbi, instructionSet, invokeWith, app.startTime); 4. AMS的startProcess private ProcessStartResult startProcess(String hostingType, String entryPoint,ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
String seInfo, String requiredAbi, String instructionSet, String invokeWith,long startTime) { startResult = Process.start(entryPoint,app.processName, uid, uid, gids, runtimeFlags, mountExternal,
app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,app.info.dataDir, invokeWith,new String[] {PROC_START_SEQ_IDENT + app.startSeq}); 方法的注解: 這個方法做的主要工作就是調用Process的靜态方法啟動一個新的程序,啟動新的程序的過程大概是,Zygote程序會fork一個新的子程序出來,子程序建立完成之後,classLoader加載ActivityThread類并建立一個ActivityThread執行個體,反射調用ActivityThread的main方法。這樣ActivityThread主線程就在新的程序中啟動起來了。接着看ActivityThread的main方法,此時已經在新的程序中執行了。我們來看ActivityThread的main方法。
轉載于:https://www.cnblogs.com/liunx1109/p/11124753.html