1. 程式人生 > 其它 >Activity的啟動流程

Activity的啟動流程

考察要點:

  • 啟動Activity會經歷哪些生命週期回撥
  • 冷啟動大致流程,涉及哪些元件,通訊過程是怎麼樣的?
  • Activity啟動過程中,生命週期回撥的原理?

總的流程圖:

1. 程序A與AMS的互動過程

此處以跨程序啟動Activity分析一下原始碼流程:

  1. A呼叫startActivity時,需要與AMS互動,此時需要需要獲取到AMS的代理物件Binder也就是上圖的AMP,通過ActivityManagerNative.getDefault()獲得,並呼叫AMP的startActivity方法,然後會通過mRemote.transact方法進行Binder通訊,在AMS的onTransact方法裡面會獲取到請求的Activity引數資訊:

    mRemote.transact(START_ACTIVITY_TRANSACTION,data,reply,0);
    ...
    
    @Override
    public boolean onTransact(int code, Parcel data, Parcel reply, int flags){
           switch(code){
               case START_ACTIVITY_TRANSACTION:{        
                   startActivity(app,callingPackage,intent,...)
               }
           }
    }
    
    
  2. AMS裡面的startActivity方法最主要會去呼叫startSpecificActivityLocked函式,在此函式裡面會去判斷目標程序是否已經存在,並且目標向AMS註冊過它自己的ApplicationThread也就是上圖ATP代理物件,如果這兩個條件都滿足會去呼叫realStartActivityLocked方法,這個方法我們後面再看。如果上述條件不滿足時,會去呼叫mService.startProcessLocked(r.processName,...)方法啟動程序。

2. AMS啟動目標程序B

       ![](https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2020/2/7/1702043547d09967~tplv-t2oaga2asx-watermark.image)
  1. startProcessLocked方法首先呼叫Process.start("android.app.ActivityThread",)方法會向Zygote傳送一個啟動程序的請求,並告知Zygote程序啟動之後,載入ActivityThread這個類的入口main函式,啟動完成後返回程序的pid,並向AMS的Handler傳送一個延遲訊息,為的是要求目標程序啟動後,10秒鐘內需要向AMS報告,不然的話AMS就會清除目標程序的相關資訊。

  2. Process.start方法會去呼叫startViaZygote(processClass,)函式,這個函式主要做了兩件事,一件就是開啟通往Zygote的Socket,第二件事就是通過Socket傳送啟動程序引數。

  3. Zygote端主要邏輯是在runOnce函式,函式內呼叫Zygote.forkAndSpecialize(...)建立子程序,建立完成之後就分別在父程序和子程序裡面做各自的事情

  4. 父程序通過hanleParentProc(pid)把子程序的pid通過Socket傳送給AMS

  5. 子程序呼叫handleChildProc函式,做一些通用的初始化,比如啟用Binder機制;執行應用程式的入口函式,也就是ActivityThread的Main函式

  6. ActivityThread的main函式,裡面會建立一個ActivityThread物件,並呼叫thread.attach(false),為的是向AMS報到,上面第一條裡面有提到。

  7. attach方法裡面,其實是一個跨程序的呼叫,首先通過

    IActivityManager mgr = ActivityManagerNative.getDefault();
    
    

    獲取到AMS的Binder代理物件,然後呼叫

    mgr.attachApplication(mAppThread);
    
    

    mAppThread是應用端的一個Binder物件ApplicationThread,也就是最上面一張圖的ATP,這樣AMS端就可以呼叫應用端了。

  8. attachApplication方法裡面,最主要有兩個方法,一個是通過傳入的ApplicationThread物件,呼叫bindApplication初始化Application物件,另一個就是通過

    mStactSupervisor.attachApplicationLoacked(app);
    
    

    初始化掛起的Activity物件。

  9. 在attachApplicationLoacked函式裡,會呼叫

    ActivityRecord hr = stack.topRunningActivityLocked(null);
    
    

    其中要明白AMS裡面有兩個棧,一個是Launch桌面棧,一個就是非桌面棧mFocusedStack,此處的stack就是mFocusedStack,它會將棧頂的ActivityRecord返回出來,我們的目標Activity早就放置在了棧頂,只是一直沒有初始化。然後呼叫

    realStartActivityLocked(hr,app,true,true);
    
    

    方法,來啟動Activity,如果我們不是啟動另外一個程序,而是同一程序,那麼這第二大部分就不會存在了,而是直接呼叫realStartActivityLocked方法。

3. 應用端Activity啟動的幾個步驟

  1. realStartActivityLocked函式會呼叫app.thread.scheduleLaunchActivity(new Intent(r.intent),...);也就是通過之前註冊的Binder物件ATP,呼叫scheduleLaunchActivity函式,在scheduleLaunchActivity函式裡面:

    ActivityClientRecord r = new ActivityClientRecord();
    ...
    sendMessage(H.LAUNCH_ACTIVITY,r);
    
    

    封裝了一個ActivityClientRecord訊息,然後丟到主執行緒的Handler(mH)裡。

  2. 在主執行緒裡面

    final ActivityClientRecord r = (ActivityClientRecord)msg.obj ;
    r.packageInfo = getPackageInfoNoCheck(...);
    handleLaunchActivity(r,null);
    
    

    getPackageInfoNoCheck 函式主要是用來生成一個LoadedApk物件,它用來儲存我們的apk資訊,因為後面我們需要一個ClassLoader去載入Apk裡面的Activity類,所以這裡提前準備好。

  3. handleLaunchActivity裡面分為兩個部分,一個是performLaunchActivity函式,一個是handleResumeActivity函式。

  4. performLaunchActivity

    Activity activity = mInstrumentation.newActivity(...);
    
    //返回之前建立好的
    Application app = r.packageInfo.makeApplication(false,mInstrumentation);
    
    //生成ContextImpl
    Context appContext = createBaseContextForActivity(r,activity);
    
    //給activity繫結上下文和一些初始化的工作,如createPhoneWindow
    activity.attach(appContext,...);
    
    mInstrumentation.callActivityOnCreate(activity,r.state); //生命週期的OnCreate
    
    activity.performStart();    //生命週期的OnStart
    
    return activity
    
    
  5. handleResumeActivity:

    -> r.activity.performResume()     
       -> mInstrumentation.callActivityOnResume(this);
         -> activity.onResume()
    
    

相關視訊推薦

【安卓面試合集】startActivity面試點01
Android(安卓)開發零基礎從入門到精通

本文轉自 https://juejin.cn/post/6844904058688372750,如有侵權,請聯絡刪除。