Activity启动流程之一

316 阅读6分钟

App的启动一般分为两种:

1. Launcher向AMS发送启动Activity

用户点击App图标的启动和调用App内部调用startActivity,这里只分析第一种的启动,相对于来说第一种更加全面

前言 手机桌面显示的很多App图标界面就是一个App,手机在启动的时候会扫描已安装apk的启动信息等并显示,
在点击某一App时就是在LauncherActivity里面的onListItemClick执行Activity的“startActivity”


@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
    Intent intent = intentForPosition(position);
    startActivity(intent);
}

@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
    ……
    if (options != null) {
        startActivityForResult(intent, -1, options);
    } else {
        startActivityForResult(intent, -1);
    }
}

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
        @Nullable Bundle options) {
    ……
     Instrumentation.ActivityResult ar =
            mInstrumentation.execStartActivity(
                this, mMainThread.getApplicationThread(), mToken, this,
                intent, requestCode, options);
    ……
}

对于每一个android app来说,它的总入口都是ActivityThread::main. 每一个应用的进程都有一个ActivityThread对象,而每一个ActivityThread对象都有一个Instrumentation,而Instrumentation在ActivityThread里面通过hanldLaunchActivity实例化Activity后通过attch将mInstrumentation透传进来的,而Instrumentation的实例化是在ActivityThread的main方法通过ActivityThread.attch里面被实例化的,有点偏了,总之现在执行还在Launcher里面这个mInstrumentation当然是还属于它,通过它的execStartActivity方法来继续完成启动Activity的流程,要注意的是这个方法中传入了mMainThread.getApplicationThread(),它获取到的是ActivityThread的内部类ApplicationThread实例,这是一个Binder对象,之后AMS通过此对象与App通信

//Instrumentation.java
public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, String resultWho,
        Intent intent, int requestCode, Bundle options, UserHandle user) {
    IApplicationThread whoThread = (IApplicationThread) contextThread;
    try {
        int result = ActivityTaskManager.getService().startActivityAsUser(whoThread,
                who.getBasePackageName(), who.getAttributionTag(), intent,
                intent.resolveTypeIfNeeded(who.getContentResolver()), token, resultWho,
                requestCode, 0, null, options, user.getIdentifier());
        checkStartActivityResult(result, intent);
    } catch (RemoteException e) {
        throw new RuntimeException("Failure from system", e);
    }
}


//ActivityTaskManager.java
public static IActivityTaskManager getService() { return IActivityTaskManagerSingleton.get(); } private static finalSingleton<IActivityTaskManager> IActivityTaskManagerSingleton = new Singleton<IActivityTaskManager>() {@Override protected IActivityTaskManager create() { final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE); return IActivityTaskManager.Stub.asInterface(b); } } };

public static IActivityTaskManager getService() {
    return IActivityTaskManagerSingleton.get();
}

@UnsupportedAppUsage(trackingBug = 129726065)
private static final Singleton<IActivityTaskManager> IActivityTaskManagerSingleton =
        new Singleton<IActivityTaskManager>() {
            @Override
            protected IActivityTaskManager create() {
                final IBinder b = ServiceManager.getService(Context.ACTIVITY_TASK_SERVICE);
                return IActivityTaskManager.Stub.asInterface(b);
            }
        };

在这里Launcher开始向AMS通信,由于是不同的进程所以需要进程间的通讯通过Binder,IActivityTaskManager代理AMS端的Binder对象,然后AMS开始startActivity,Launcher向AMS请求启动一个App这一流程就结束了

2. AMS启动Activity并通知Launcher进入Paused状态

接下来我们要到AMS所在的进程分析与IActivityTaskManager通信的是ActivityTaskManagerService

@Override
public final int startActivity(IApplicationThread caller, String callingPackage,
        String callingFeatureId, Intent intent, String resolvedType, IBinder resultTo,
        String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo,
        Bundle bOptions) {
    return startActivityAsUser(caller, callingPackage, callingFeatureId, intent, resolvedType,
            resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions,
            UserHandle.getCallingUserId());
}

private int startActivityAsUser(IApplicationThread caller, String callingPackage,
        @Nullable String callingFeatureId, Intent intent, String resolvedType,
        IBinder resultTo, String resultWho, int requestCode, int startFlags,
        ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) {
    return getActivityStartController().obtainStarter(intent, "startActivityAsUser")
            .setCaller(caller)
            .setCallingPackage(callingPackage)
            .setCallingFeatureId(callingFeatureId)
            .setResolvedType(resolvedType)
            .setResultTo(resultTo)
            .setResultWho(resultWho)
            .setRequestCode(requestCode)
            .setStartFlags(startFlags)
            .setProfilerInfo(profilerInfo)
            .setActivityOptions(bOptions)
            .setUserId(userId)
            .execute();
}

ActivityStarter obtainStarter(Intent intent, String reason) {
    return mFactory.obtain().setIntent(intent).setReason(reason);
}

上面主要是做权限的检查等

//ActivityStarter.java
execute()-->executeRequest()
最终一层层调用到这里
//ActivityStack.java
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
...
if (mResumedActivity != null) {
    if (DEBUG_STATES) Slog.d(TAG_STATES,
            "resumeTopActivityLocked: Pausing " + mResumedActivity);
            //通知Launcher进入Paused状态
    pausing |= startPausingLocked(userLeaving, false /* uiSleeping */, next);
}
...
//启动新的activity准备
mStackSupervisor.startSpecificActivity
...
}
//ActivityStackSupervisor.java
void startSpecificActivity(ActivityRecord r, boolean andResume, boolean checkConfig) {
    // Is this activity's application already running?
    final WindowProcessController wpc =
            mService.getProcessController(r.processName, r.info.applicationInfo.uid);

    boolean knownToBeDead = false;
    //如果该启动app的进程存在,就是在同应用的Activity启动,《普通Activity的启动就在这里》
    if (wpc != null && wpc.hasThread()) {
        try {
            realStartActivityLocked(r, wpc, andResume, checkConfig);
            return;
        } catch (RemoteException e) {
            Slog.w(TAG, "Exception when starting activity "
                    + r.intent.getComponent().flattenToShortString(), e);
        }

        // If a dead object exception was thrown -- fall through to
        // restart the application.
        knownToBeDead = true;
    }
    //通过AMS向Zygote进程请求创建新的app进程
    r.notifyUnknownVisibilityLaunchedForKeyguardTransition();

    final boolean isTop = andResume && r.isTopRunningActivity();
    mService.startProcessAsync(r, knownToBeDead, isTop, isTop ? "top-activity" : "activity");
}

到这里完成了Launcher和AMS的通信,以及AMS和Zygote进程的通信 接下来创建要启动的App的线程ActivityThread-->main,一个全新的实例化过程就要开始了

3.新的进程启动,ActivityThread的main函数入口

上面说到zygote孵化新的进程后通过反射调用了main函数 之后的流程就在新的App进程进行了

public static void main(String[] args) {

    
    Looper.prepareMainLooper();

    ActivityThread thread = new ActivityThread();
    thread.attach(false, startSeq);
    
    Looper.loop();

}


private void attach(boolean system, long startSeq) {

    ...
    //绑定Application
    final IActivityManager mgr = ActivityManager.getService();
    try {
        mgr.attachApplication(mAppThread, startSeq);
    } catch (RemoteException ex) {
        throw ex.rethrowFromSystemServer();
    }
    ...

}

//ActivityManagerService.java
@Override
public final void attachApplication(IApplicationThread thread, long startSeq) {
    if (thread == null) {
        throw new SecurityException("Invalid application interface");
    }
    synchronized (this) {
        attachApplicationLocked(thread, callingPid, callingUid, startSeq);
    }
}


private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
        int pid, int callingUid, long startSeq) {
        
   
    thread.bindApplication(processName, appInfo, providerList,
            instr2.mClass,
            profilerInfo, instr2.mArguments,
            instr2.mWatcher,
            instr2.mUiAutomationConnection, testMode,
            mBinderTransactionTrackingEnabled, enableTrackAllocation,
            isRestrictedBackupMode || !normalMode, app.isPersistent(),
            new Configuration(app.getWindowProcessController().getConfiguration()),
            app.compat, getCommonServicesLocked(app.isolated),
            mCoreSettingsObserver.getCoreSettingsLocked(),
            buildSerial, autofillOptions, contentCaptureOptions,
            app.mDisabledCompatChanges);
 
   didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());

        
}

//这里主要是创建了Looper和ActivityThread对象,然后将当前应用ApplicationThread注册到AMS中,
ApplicationThread是ActivityThread的内部类实现了IApplicationThread.Stub用此对象可跨进程通信。


AMS绑定ApplicationThread发送了一个mH.BindApplication的message,在内部Hander处理调用application.oncreate

//ActivityThread
void bindApplication(){

    sendMessage(H.BIND_APPLICATION, data);

}


public void handleMessage(Message msg) {
    if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
    switch (msg.what) {
        case BIND_APPLICATION:
            Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
            AppBindData data = (AppBindData)msg.obj;
            handleBindApplication(data);
            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            break;
}


private void handleBindApplication(AppBindData data) {
    try {
        mInstrumentation.callApplicationOnCreate(app);
    }
}


到这里,新的app线程已将启动并绑定了Application,接下来就是activity的创建

//ActivityStackSupervisor.java


boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
        boolean andResume, boolean checkConfig) throws RemoteException {


    // Create activity launch transaction.
    final ClientTransaction clientTransaction = ClientTransaction.obtain(
            proc.getThread(), r.appToken);

    final DisplayContent dc = r.getDisplay().mDisplayContent;
    clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
            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, proc.getReportedProcState(),
            r.getSavedState(), r.getPersistentSavedState(), results, newIntents,
            dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
            r.assistToken, r.createFixedRotationAdjustmentsIfNeeded()));


    // Set desired final state.
    final ActivityLifecycleItem lifecycleItem;
    if (andResume) {
        lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
    } else {
        lifecycleItem = PauseActivityItem.obtain();
    }
    clientTransaction.setLifecycleStateRequest(lifecycleItem);

    // Schedule transaction.
    mService.getLifecycleManager().scheduleTransaction(clientTransaction);

    //ClientTransaction管理了Activity的启动信息,LaunchActivityItem继承
    ActivityLifecycleItem,具象化了Activity的生命周期,并可ClientLifecycleManager由执行,
    接下来`scheduleTransaction`方法中发送了EXECUTE_TRANSACTION的消息给ActivityThread的H类处
    理,然后再执行`TransactionExecutor.execute()`,最后执行`handleLaunchActivity`方法,如下
}

void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
    final IApplicationThread client = transaction.getClient();
    transaction.schedule();
    if (!(client instanceof Binder)) {
        // If client is not an instance of Binder - it's a remote call and at this point it is
        // safe to recycle the object. All objects used for local calls will be recycled after
        // the transaction is executed on client in ActivityThread.
        transaction.recycle();
    }
}
//ClientTransaction.java
public void schedule() throws RemoteException {
    mClient.scheduleTransaction(this);
}

上面那个Client就是IApplicationThread就是ActivityThread,而ActivityThread里面自己调用了自己, 所以我们看看它的父类ClientTransactionHandler里面的scheduleTransaction

void scheduleTransaction(ClientTransaction transaction) {
    transaction.preExecute(this);
    sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
case EXECUTE_TRANSACTION:
    final ClientTransaction transaction = (ClientTransaction) msg.obj;
    mTransactionExecutor.execute(transaction);
    if (isSystem()) {
        // Client transactions inside system process are recycled on the client side
        // instead of ClientLifecycleManager to avoid being cleared before this
        // message is handled.
        transaction.recycle();
    }
//TransactionExecutor.java

    public void execute(ClientTransaction transaction) {

        executeCallbacks(transaction);

        executeLifecycleState(transaction);

    }



    switch (state) {
        case ON_CREATE:
            mTransactionHandler.handleLaunchActivity(r, mPendingActions,
                    null /* customIntent */);
            break;

最终回到ActivityThread的 handleLaunchActivity
public Activity handleLaunchActivity(ActivityClientRecord r,
        PendingTransactionActions pendingActions, Intent customIntent) {
        
    //实例化Activity
        final Activity a = performLaunchActivity(r, customIntent);
             
        activity.attach(appContext, this, getInstrumentation(), r.token,
                r.ident, app, r.intent, r.activityInfo, title, r.parent,
                r.embeddedID, r.lastNonConfigurationInstances, config,
                r.referrer, r.voiceInteractor, window, r.configCallback,
                r.assistToken);
                

        if (r.isPersistable()) {
            mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
        } else {
            mInstrumentation.callActivityOnCreate(activity, r.state);
        }


}


private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
  
        try {
            java.lang.ClassLoader cl = appContext.getClassLoader();
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
            StrictMode.incrementExpectedActivityCount(activity.getClass());
            r.intent.setExtrasClassLoader(cl);
            r.intent.prepareToEnterProcess();
            if (r.state != null) {
                r.state.setClassLoader(cl);
            }
        } 

    本质--》(Activity) cl.loadClass(className).newInstance()
}

//Activity.java
final void attach(Context context, ActivityThread aThread,
        Instrumentation instr, IBinder token, int ident,
        Application application, Intent intent, ActivityInfo info,
        CharSequence title, Activity parent, String id,
        NonConfigurationInstances lastNonConfigurationInstances,
        Configuration config, String referrer, IVoiceInteractor voiceInteractor,
        Window window, ActivityConfigCallback activityConfigCallback, IBinder assistToken) {
       //绑定上下文
        attachBaseContext(context);
        //实例化Window对象
        mWindow = new PhoneWindow(this, window, activityConfigCallback);
       //记录当前线程
       mUiThread = Thread.currentThread()
        //设置WindowManager
        mWindow.setWindowManager(
        (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
        mToken, mComponent.flattenToString(),
        (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
        
        
}

总结:

  • 点击图标,Launcher 向 AMS 请求启动该 App

  • AMS 反馈收到启动请求,并告知 Launcher 进入 pause 状态

  • Launcher 进入Paused 状态并告知 AMS

  • AMS 检测新的 App 是否已启动,否则通知 Zygote 创建新的进程并调用 ActivityThread.main 方法

  • 应用进程启动 ActivityThread

  • ActivityThread 中 H 类处理需要启动 Activity 的请求消息