【Android framework】am命令啟動Activity流程


源碼基於Android 4.4。
 
am start -W -n com.dfp.test/.TEstActivity
-W:等目標Activity啟動后才返回
-n:用於設置Intent的Component
 
Am.java->run()->runStart()
——intent = makeIntent();
——intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
——mAm. startActivityAndWait();                                        //調用AMS處理startActivityAndWait
ActivityManagerService.java->startActivityAndWait(......)
//一般情況下Activity是由另一個應用發起的,此時IApplicationThread是應用和AMS交互的通道,也可算是調用進程的表示。am不是一個應用進程,所以IApplicationThread caller變量為null。
//requestCode為調用者發送的代碼,具體含義由調用者解釋。如果該值大於0,AMS會保存該值並通過onActivityResult返回給調用者。用於記錄啟動了哪個Activity的功能
————mMainStack.startActivityMayWait()                     //4.4中為mStackSupervisor.startActivityMayWait()
//Activity調度需要 ActivityStack,是核心角色
//Activity對應管理類為 ActivityRecord表示
//Task由一組Activity組成,用於完成一組特定的功能,對應管理類為 TaskRecord表示。同一時間只有以個Task可以顯示在前台,其余在后台。Task中只有最前端的Activity可以運行,其他會停止運行。以前很多應用,一個Task里的Activity都在同一個Application中,現在很多Task可以由不同Application的Activity組成。
//ActivityStack只保存ActivityStack不保存TaskRecord。直接管理ActivityStack,弱化了Task的概念。提高了效率,降低了結構清晰度。
 
ActivityStackSupervisor.java->startActivityMayWait()
4.4中新增了mStackSupervisor,部分函數從ActivityStack移到ActivityStackSupervisor,ActivityStack的一些調用會使用mActivityStackSupervisor進行,反之亦是。
對 Task 的操作,AMS 使用 mStackSupervisor 來進行。對於 Acitivity 的操作,AMS 使用 ActivityStack 來進行。
系統中只有兩個 ActivityStack,一個是 mHomeStack,用於保存 Launcher 的Activity,另一個是 mFocusedStack,用於保存非 Launcher 的 App 的 Activity。
第一階段:獲取資源和變量
——intnent.getcomponent();                                             //查找Component,如果Component存在,則省去匹配搜索Intent(本例不為null)
——aInfo = resolveActivity();                                             //查詢滿足條件的ActivityInfo,在resolveActivity內部與uPKMS交互
——callingPid = Binder.getCallingPid();                            //獲取調用進程的PID,UID
——callingUid = Binder.getCallingUid();
第二階段:啟動Activity
——int res =  startActivityLocked();                                    //啟動Activity
————sourceRecord = isInAnyStackLocked();                //發送請求的ActivityRecord
————resultRecord = sourceRecord.resultTo;                //接收啟動結果的ActivityRecord。通常是同一個
————callerApp = mService.getRecordForAppLocked(caller);          //如果caller不為空,需要找到對應的ProcessRecord,從而獲得PID/VID
————launchFlags = intent.getFlags();                            //獲取啟動Flags
————mService.checkPermission();                                //檢查權限
————mService.checkComponentPermission();
————mService.mController.activityStarting();                //(Monkey測試)交給回調對象處理,由他判斷是否能繼續后面的行程
————ActivityRecord r = new ActivityRecord();              //創建一個ActivityRecord對象
————mService.checkAppSwitchAllowedLocked(callingPid, callingUid);     //檢查調用進程是否有權限切換Application,如果沒有則儲存起來,有機會再啟動它。將保存到mPendingActivityLaunchers中
//沒有權限切換意味着當前顯示的應用進行了stopAppSwitches。這個方法會使其他Task的Activity無法顯示在前端,但同一個Task中的Activity則不受制約。取消禁止切換使用resumeAppSwitches。為了防止使用者不調用resumeAppSwitches,系統設置了一個超時時間(5s),超時則自動resume。在resume中不會處理Pending起來的Activity,但超時會觸發處理Pending的Activity。
————mService.doPendingActivityLaunchesLockedd(false);          //啟動處於Pending狀態的Activity,即之前由於上一步被禁止切換而保存起來的請求。它將先於本次需要啟動的Activity處理
———— startActivityUncheckedLocked();                          //處理啟動請求,為新建的ActivityRecord找到合適的Task
——————//單獨分析
——mService.updateConfigureationLocked();                    //如果configuration發生變化,則調用AMS更新configuration
第三階段:處理結果
——outResult.result = res;                                                 //設置啟動結果
——if (res == IActivityManager.START_SUCCESS) mService.wait();            //如果啟動成功了,等待啟動結果。為什么res返回成功還要等待呢?因為Activity要運行在一個新的應用i進程中,就必須等待那個應用進程正常啟動並處理相關請求。注意,只有am設置了-W選項,才會進入wait狀態。
——if (err != START_SUCCRSS) sendActivityResultLocked(); return err;     //如果有問題,則返回錯誤
 
 
startActivityUncheckedLocked()
第一階段
int launchFlags = intent.getFlags();
launchFlags |= Intent.FLAG_ACTIVITY_NEW_TASK;               //根據sourceRecord.launchMode判斷是否需要設置FLAG_ACTIVITY_NEW_TASK。
第二階段
boolean addingToTask = false;
boolean movedHome = false;
ActivityRecord intentActivity = r.launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE ? findTaskLocked(r) : findActivityLocked(intent, r.info);
r.task = intentActivity.task;                                                  //ActivityRecord r
targetStack = intentActivity.task.stack;
//找到合適的Task做一些ActivityStack中的處理
第三階段
boolean newTask = false;
boolean keepCurTransition = false;
//增加一個Task,如果前面設置了FLAG_ACTIVITY_NEW_TASK
mService.curTask++;                                                           //當前Task數量加一

版權所有,轉載請注明出處:

http://www.cnblogs.com/sickworm/p/4220139.html  

 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM