Android Activity啓動流程(基於Android8.0系統)

主要對象介紹

  • ActivityManagerService:負責系統中全部Activity的生命週期;
  • ActivityThread:App的真正入口,當App啓動後,會調用其main方法開始執行,開啓消息循環隊列。是傳說中的UI線程,即主線程。與ActivityManagerService配合,一塊兒完成Activity的管理工做;
  • ApplicationThread:用來實現ActivityManagerService與ActivityThread之間的交互。在ActivityManagerService須要管理相關Application中的Activity的生命週期,經過ApplicationThread的代理對象與ActivityThread通信;
  • ApplictationThreadProxy:是ApplicationThread在服務端的代理對象,負責和客戶端的ApplicationThread通信。AMS就是經過這個代理對象與ActivityThread進行通訊的,Android 8.0上以刪除該類,採用AIDL接口的方式來進行IPC,實現RPC操做
  • Instrumentation:每個應用程序都只有一個Instrumentation對象,每一個Activity內都有一個對該對象的引用。Instrumentation能夠理解爲應用進程的管家,ActivityThread要建立或者打開某個Activity時,都須要經過Instrumentation來進行具體的操做;
  • ActvitityStack:Activity在AMS的棧管理,用來記錄已經啓動的Activity的前後關係、狀態信息等。經過ActivityStack決定是否須要啓動新的進程;
  • ActivityRecord:ActivityStatck的管理對象,每一個Activity在AMS對應的一個ActivityRecord,來記錄Activity的狀態以及其餘信息。能夠理解爲Activity在服務端的Activity對象的映射;
  • ActivityClientRecord:與ActivityRecord是在服務端(AMS)的記錄相對應,是Activity在客戶端(ActivityThread)的記錄;
  • TaskRecord:AMS抽象出來的任務棧的概念。一個TaskRecord包含若干個ActivityRecord。ASM用它來確保Activity啓動和退出順序。它與Activity的啓動模式直接相關。
  • ActivityStarter:啓動Activity的控制器,主要用於用來將Intent和flags轉換成activity和相關任務棧;
  • ActivityStackSupervisor:主要管理着mHomeStack和mFocusedStack兩個ActivityStack等相關信息;

Binder通訊

  • 在Android 8.0之前,Binder通訊的流程以下:
    客戶端: ActivityManagerProxy -> Binder驅動 -> 服務端:ActivityManagerService
    服務端: ApplicationThreadProxy -> Binder驅動 -> 客戶端:ApplicationThread
  • Android8.0開始,刪除了ActivityManagerNative,AMS的繼承類也發生了變化,繼承了IActivityManager.Stub接口類。瞭解Android的Binder機制應該知道,這裏IActivityManager.aidl生成的接口類。Android8.0開始,把一些Binder代碼轉化爲了AIDL模板方式:
public class ActivityManagerService extends IActivityManager.Stub
        implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback

ActivityManager中的代碼:app

public static IActivityManager getService() {
        return IActivityManagerSingleton.get();
    }

    private static final Singleton<IActivityManager> IActivityManagerSingleton =
            new Singleton<IActivityManager>() {
                @Override
                protected IActivityManager create() {
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                    final IActivityManager am = IActivityManager.Stub.asInterface(b);
                    return am;
                }
            };
  • 而在Android7.0及其之前的版本上,則是客戶端經過ActivityManaagerProxy與服務端的ActivityManager進行通訊的
    ActivityManagerNative:
**
*得到IActivityManager類
*/
static public IActivityManager getDefault() {
        return gDefault.get();
    }

static public IActivityManager asInterface(IBinder obj) {
        if (obj == null) {
            return null;
        }
        IActivityManager in =
            (IActivityManager)obj.queryLocalInterface(descriptor);
        if (in != null) {
            return in;
        }
 
        return new ActivityManagerProxy(obj);

}

ActivityManager:async

private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() {
        protected IActivityManager create() {
            IBinder b = ServiceManager.getService("activity");
            if (false) {
                Log.v("ActivityManager", "default service binder = " + b);
            }
            IActivityManager am = asInterface(b);//注意這一行
            if (false) {
                Log.v("ActivityManager", "default service = " + am);
            }
            return am;
        }
};

能夠看出來,兩個寫法不同,本質上都是同樣的,Android 8.0可能使用了AIDL方式進行ipc。ide

  • 同理,ApplicationThread同上述同樣作了更改:
private class ApplicationThread extends IApplicationThread.Stub {
    ...
 }

因此在Android 8.0上不存在ActivityManagerProxy和ApplicationThreadProxy,而是採用了AIDL接口的方式來進行通訊的。post

源碼調用棧(基於Android 8.0)

按照自上而下的調用棧的順序進行調用,以類文件爲單位來計步,方便你們去了解調用流程,主要涉及的幾個源文件:Instumentation,ActivityMangerService,ActivityStack,ActivityStarter,ActivityStackSupervisor,ActivityThread,Activity等。ui

  1. Activity
public void startActivity(Intent intent)
    
public void startActivity(Intent intent, @Nullable Bundle options)

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
            @Nullable Bundle options)
  1. Intrumentation
public ActivityResult execStartActivity(
    Context who, IBinder contextThread, IBinder token, Activity target,
    Intent intent, int requestCode, Bundle options){
    ...
    int result = ActivityManager.getService()
        .startActivity(whoThread, who.getBasePackageName(), intent,
            intent.resolveTypeIfNeeded(who.getContentResolver()),
            token, target != null ? target.mEmbeddedID : null,
            requestCode, 0, null, options);
    ...
}
  1. ActivityManagerService
public final int startActivity(IApplicationThread caller, String callingPackage,
    Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
    int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
    ...
    return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
                resultWho, requestCode, startFlags, profilerInfo, bOptions,
                UserHandle.getCallingUserId());
}
     
            
public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
    Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
    ...
    return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
                resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
                profilerInfo, null, null, bOptions, false, userId, null, "startActivityAsUser");
}
  1. ActivityStarter
final int startActivityMayWait(IApplicationThread caller, int callingUid,
    String callingPackage, Intent intent, String resolvedType,
    IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
    IBinder resultTo, String resultWho, int requestCode, int startFlags,
    ProfilerInfo profilerInfo, WaitResult outResult,
    Configuration globalConfig, Bundle bOptions, boolean ignoreTargetSecurity, 
    int userId,askRecord inTask, String reason) { 
    ...
    int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
        aInfo, rInfo, voiceSession, voiceInteractor,
        resultTo, resultWho, requestCode, callingPid,
        callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
        options, ignoreTargetSecurity, componentSpecified, outRecord, inTask,
        reason);
    ...
}
        

int startActivityLocked(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
    String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
    IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
    IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
    String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
    ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
    ActivityRecord[] outActivity, TaskRecord inTask, String reason) {
    ...
    mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
    aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
    callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
    options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
            inTask);
    ...
}
            
private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
    String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
    IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
    IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
    String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
    ActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
    ActivityRecord[] outActivity, TaskRecord inTask) {
    ...
    doPendingActivityLaunchesLocked(false);
    return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true,
    options, inTask, outActivity);
}
            

private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
    IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
    int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
    ActivityRecord[] outActivity) {
    ...
    result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
        startFlags, doResume, options, inTask, outActivity);
    ...
}  
            
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
    IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
    int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
    ActivityRecord[] outActivity) {
    ...
    if (mDoResume) {
        mSupervisor.resumeFocusedStackTopActivityLocked();
    }
    ...
}
  1. ActivityStackSupervisor
boolean resumeFocusedStackTopActivityLocked() {
    return resumeFocusedStackTopActivityLocked(null, null, null);
}
    
boolean resumeFocusedStackTopActivityLocked(
    ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
    ...
    if (r == null || r.state != RESUMED) {
        mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
    } 
    ...
}
  1. ActivityStack
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
    ...
    result = resumeTopActivityInnerLocked(prev, options);
    ...
}

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) { 
   ....
    if (mResumedActivity != null) {
        //同步等待pause當前Activity的結果
        pausing |= startPausingLocked(userLeaving, false, next, false);
    }
    ....
      //開始啓動下一個Activity
      mStackSupervisor.startSpecificActivityLocked(next, true, false);
    ....
}


final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping, ActivityRecord resuming, boolean pauseImmediately) {
    ....
    //去當前Activity所在應用進程暫停當前activity
     prev.app.thread.schedulePauseActivity(prev.appToken, prev.finishing,
            userLeaving, prev.configChangeFlags, pauseImmediately);
    ....
}
  1. ActivityThread$ApplicationThread
public final void schedulePauseActivity(IBinder token, boolean finished, boolean userLeaving, int configChanges, boolean dontReport) {
    ...
    sendMessage(finished ? H.PAUSE_ACTIVITY_FINISHING: H.PAUSE_ACTIVITY, token,
    (userLeaving ? USER_LEAVING: 0) | (dontReport ? DONT_REPORT: 0), configChanges, seq);
    ...
}
  1. ActivityThread
private void sendMessage(int what, Object obj, int arg1, int arg2, int seq) {
    Message msg = Message.obtain();
    ....
    mH.sendMessage(msg);
}
  1. ActivityThread$H
public void handleMessage(Message msg) {
   ...
    switch (msg.what) {
    case PAUSE_ACTIVITY:
        {
            SomeArgs args = (SomeArgs) msg.obj;
            handlePauseActivity((IBinder) args.arg1, false, (args.argi1 & USER_LEAVING) != 0,
            args.argi2, (args.argi1 & DONT_REPORT) != 0, args.argi3);
        }
        break;
    }
    ...
}
  1. ActivityThread
private void handlePauseActivity(IBinder token, boolean finished, 
    boolean userLeaving, int configChanges, boolean dontReport, int seq) {
    ...
    performPauseActivity(token, finished, r.isPreHoneycomb(), "handlePauseActivity");
    ...
    //執行完後通知AMS當前Activity已經pause
    ActivityManager.getService().activityPaused(token);
    ...
}

final Bundle performPauseActivity(ActivityClientRecord r, boolean finished,
     boolean saveState, String reason) {
         ...
         performPauseActivityIfNeeded(r, reason);
         ...
}


private void performPauseActivityIfNeeded(ActivityClientRecord r, String reason) {
    ...
     mInstrumentation.callActivityOnPause(r.activity);
    ...
}
  1. Instrumentation
public void callActivityOnPause(Activity activity) {
    activity.performPause();
}
  1. Activity
final void performPause() {
    ...
    onPause();
    ...
}

因爲在ActivityThread中handlePauseActivity的方法裏,在pause成功後,須要通知AMS已經pause成功,因此接着分析ActivityManagerService.activityPaused方法。this

  1. ActivityManagerService
public final void activityPaused(IBinder token) {
    final long origId = Binder.clearCallingIdentity();
    synchronized(this) {
        ActivityStack stack = ActivityRecord.getStackLocked(token);
        if (stack != null) {
            stack.activityPausedLocked(token, false);
        }
    }
    Binder.restoreCallingIdentity(origId);
}
  1. ActivityStack
final void activityPausedLocked(IBinder token, boolean timeout) {
    ...
    mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
    ...
    completePauseLocked(true /* resumeNext */, null /* resumingActivity */);
    ...
}

private void completePauseLocked(boolean resumeNext, ActivityRecord resuming) {
    ...
    mStackSupervisor.resumeFocusedStackTopActivityLocked(topStack, prev, null);
    ...
}
  1. ActivityStackSupervisor
boolean resumeFocusedStackTopActivityLocked(ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
    //若是啓動Activity和要啓動的Activity在同一個ActivityStack中,調用targetStack對象的方法
    if (targetStack != null && isFocusedStack(targetStack)) {
        return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
    }
    //若是不在同一個ActivityStack中,則調用mFocusStack對象的方法
    if (r == null || r.state != RESUMED) {
        mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
    }

    return false;
}
  1. ActivityStatck
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
    ...
    result = resumeTopActivityInnerLocked(prev, options);
    ...
}

private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) { 
   ...
    if (mResumedActivity != null) {
        //同步等待pause當前Activity的結果,但在pause時,已經把mResumedActivity置爲了null,因此不走這裏
        pausing |= startPausingLocked(userLeaving, false, next, false);
        ...
    }
    ...
    return true;
    ...
      //開始啓動下一個Activity
      mStackSupervisor.startSpecificActivityLocked(next, true, false);
    ...
}
  1. ActivityStackSupervisor
void startSpecificActivityLocked(ActivityRecord r,
    boolean andResume, boolean checkConfig) { 
    if (app != null && app.thread != null) { 
        ...
        realStartActivityLocked(r, app, andResume, checkConfig);
        return;
    }
    ...
    //啓動跨進程的Activity須要先開啓新的應用進程
    mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
        "activity", r.intent.getComponent(), false, false, true);
}

final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
    boolean andResume, boolean checkConfig) throws RemoteException { 
    ...
    app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
        System.identityHashCode(r), r.info,
        // TODO: Have this take the merged configuration instead of separate global
        // and override configs.
        mergedConfiguration.getGlobalConfiguration(),
        mergedConfiguration.getOverrideConfiguration(), r.compat,
        r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle,
        r.persistentState, results, newIntents, !andResume,
        mService.isNextTransitionForward(), profilerInfo);
    ...
}
  1. ActivityThread$ApplicationThread
public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
    ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
    CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor,
    int procState, Bundle state, PersistableBundle persistentState,
    List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents,
    boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {
    ...
    sendMessage(H.LAUNCH_ACTIVITY, r);
}
  1. ActivityThread
private void sendMessage(int what, Object obj) {
    sendMessage(what, obj, 0, 0, false);
}
 
 
private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
    ...
    mH.sendMessage(msg);
}
  1. ActivityThread$H
public void handleMessage(Message msg) {
    ...
    switch (msg.what) {
    case LAUNCH_ACTIVITY:
        {
            ....
            handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
            ....
        }
        break;
        ...
    }
}
  1. ActivityThread
private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
    ...
    Activity a = performLaunchActivity(r, customIntent);
}

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent){ 
    ...
    if (r.isPersistable()) {
        mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
    } else {
        mInstrumentation.callActivityOnCreate(activity, r.state);
    }
    ...
}
  1. Instumentation
public void callActivityOnCreate(Activity activity, Bundle icicle) {
    prePerformCreate(activity);
    activity.performCreate(icicle);
    postPerformCreate(activity);
}
  1. Activity
final void performCreate(Bundle icicle) {
    performCreate(icicle, null);
}

final void performCreate(Bundle icicle, PersistableBundle persistentState) {
    ...
    if (persistentState != null) {
        onCreate(icicle, persistentState);
    } else {
        onCreate(icicle);
    }
   ...
}

Activity啓動流程

爲了敘述方便,咱們假設Activity A要啓動Activity B。spa

  1. Activity A向AMS發送一個啓動Activity B的進程間通訊請求;
  2. AMS會將要啓動的Activity B的組件信息保存下來,而後經過Binder通訊(ApplicationThread及其接口定義語言),讓Activity A執行pause操做;
  3. Activity B完成pause操做後,經過Binder通訊(ActivityManagerService及其接口定義語言)通知AMS,能夠執行啓動Activity B的操做了(要啓動的activity信息保存在了棧頂);
  4. 在啓動以前,若是發現Activity B的應用程序進程不存在,會先啓動一個新的進程(上述調用棧沒涉及,同窗們可自行查看源碼);
  5. AMS執行一系列啓動Activity B的操做,並經過Binder通訊(ApplicationThread及其接口定義語言)進行跨進程調用,將Activity B啓動起來;

關於AMS

  • AMS的啓動是在SystemServer(系統進程)中啓動的,同其餘Android應用同樣,也是由Zygote進程fork出來的:
public final class SystemServer {

    /**
     * The main entry point from zygote.
     * 註釋寫的很清楚了,SystemServer進程是有Zygote進程fork出來的
     */
    public static void main(String[] args) {
        new SystemServer().run();
    }    
    
    private void run() {
        ...
         startBootstrapServices();
        ...
    }
    
    private void startBootstrapServices() {
        ...
        // Activity manager runs the show.
        traceBeginAndSlog("StartActivityManager");
        //開啓ActivityManagerService進程
        mActivityManagerService = mSystemServiceManager.startService(
                ActivityManagerService.Lifecycle.class).getService();
        mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
        mActivityManagerService.setInstaller(installer);
        traceEnd();        
        ...
    }    
}
  • AMS與APP進程的通訊:
  1. APP進程經過IActivityManager.aidl接口向AMS進程進行通訊。
    ActivityManager.getService()得到AMS的Binder接口,再經過Stub.asInterface的方式,轉成IActivityManager的接口,經過IActivityManager與AMS進行通訊,實現RPC遠程跨進程調用;
    Instrumentation
int result = ActivityManager.getService()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target, requestCode, 0, null, options);

ActivityManager線程

public static IActivityManager getService() {
        return IActivityManagerSingleton.get();
}
 
private static final Singleton<IActivityManager> IActivityManagerSingleton =
    new Singleton<IActivityManager>() {
        @Override
        protected IActivityManager create() {
            final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
            final IActivityManager am = IActivityManager.Stub.asInterface(b);
            return am;
        }
};
  1. AMS進程經過IApplication.aidl接口向APP進程進行通訊。 在AMS內部持有每一個ActivityThread的IApplicatinThread接口實例,用時能夠直接調用。同IActivityManager,也是經過Binder進行進程間通訊。
相關文章
相關標籤/搜索