App启动流程浅析(Android10)

谁能告诉我:怎么把代码的背景色改成黑色???

一些可以了解的知识

和启动流程相关的类

从这篇文章拿来的图片
blog.csdn.net/zplxl99/art… 20200225224905798.png

  1. ActivityTaskManagerService: 是Android 10新增加的系统服务类,可以看做帮AMS分摊工作的类
  2. ActivityStackSupervisor: 负责所有Activity栈的管理
  3. ActivityStack: 内部维护一个 TaskRecord队列 用来保存TaskRecord
  4. TaskRecord: 内部维护一个 ActivityRecord队列 用来保存ActivityRecord
  5. ActivityRecord: 代表一个activity,保存了Activity的各种信息提供给AMS使用

Launcher启动

  • 你的手机桌面就是一个Launcher进程,当你点击桌面App时。他就会通过Binder通信(跨进程通信)去请求system_server进程启动一个Activity
  • system_server进程是一个系统进程,里面基本存放了所有手机Service服务,其中管理我们App四大组件的AMS也在其中
  • 如果你的APP没启动过,AMS会请求Zygote进程去fork出你的App进程,这就是冷启动
  • 如果你的APP启动过了,已经fork出来了,那么就会直接启动你的第一个Activity,这就是热启动

image.png

Application启动流程

ActivityThread.java
从App进程被创建出来后,就会执行Main函数 通过贴出的关键代码,我们可以这样整理一下

  • main函数创建出了一个ActivityThread实例,
  • 通过ActivityManager获取到AMS实例代理
  • 调用AMS的方法attachApplication,请求创建绑定Application,并把ApplicationThread给AMS
===== ActivityThread.java =====
public static void main(String[] args) {
    ....
    // 创建出ActivityThread实例(注意这不是一个线程!!)
    ActivityThread thread = new ActivityThread();
    // 然后调用attach去做一些绑定
    thread.attach(false, startSeq);
    ....
}

==== 还是在ActivityThread.java ====
private void attach(boolean system, long startSeq) {
    // 注意这个变量,就是把当前ActivityThread实例保存在当前类的sCurrentActivityThread变量中
    sCurrentActivityThread = this;
    // 上面传入的是system = FALSE,进入
    mSystemThread = system;
    if (!system) {
        ...
        // 拿到一个IActivityManager对象,这里直接当做是AMS
        final IActivityManager mgr = ActivityManager.getService();
        try {
            // 重点方法,mgr(= AMS),也就是调用AMS的方法
            // 注意这里传入的 mAppThread 变量
            mgr.attachApplication(mAppThread, startSeq);
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
        // 添加GC内存回收的一个箭筒,感兴趣可以了解一下
        // Watch for getting close to heap limit.
        BinderInternal.addGcWatcher(new Runnable(){});
    } else {
        ....
    }
    ...
}

==== 还是在ActivityThread.java ====
通过搜索发现,mAppThread就是一个ApplicationThread实例,这个实例是ActivityThread的一个内部类
@UnsupportedAppUsage
final ApplicationThread mAppThread = new ApplicationThread();


复制代码

ActivityManagerService.java

  • 给Binder通信赋pid,uid保证安全性
  • 回到ActivityThread的ApplicationThread,调用bindApplication
==== ActivityManagerService.java ====
public final void attachApplication(IApplicationThread thread, long startSeq) {
    if (thread == null) {
        throw new SecurityException("Invalid application interface");
    }
    synchronized (this) {
        // 这里每一句话都很重要
        // 但是根据流程我们会进入到4方法中去
        // Bindder通信安全,自带验证信息就是在这里赋值的(1,2,4,5)也是Bindder安全的原因
        1.int callingPid = Binder.getCallingPid();
        2.final int callingUid = Binder.getCallingUid();
        3.final long origId = Binder.clearCallingIdentity();
        4.attachApplicationLocked(thread, callingPid, callingUid, startSeq);
        5.Binder.restoreCallingIdentity(origId);
    }
}



==== 还是 ActivityManagerService.java ====
private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
        int pid, int callingUid, long startSeq) {
    ....
    // 这里的thread就是 mAppThread=ApplicationThread()
    // 所以调用了这个函数,流程又会回到ActivityThread.java文件去
    thread.bindApplication(各种参数)
    ....
     
    // 记住bindApplication执行完毕后,流程又会回到这边来,这里先贴出代码,混个眼熟,
    if (normalMode) {
        try {
            didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
        } catch (Exception e) {
            Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
            badApp = true;
        }
    }
   
}
复制代码

ActivityThread.java

  • bindApplication会发送一个Handler消息
  • 而处理这个消息的Handler也在ActivityThread中的Class H
  • H收到消息后就会开始执行创建并绑定Application的操作
  • 并且在创建完Application后,还会初始化ContentProvide
=== 在ActivityThread.java中的内部类ApplicationThread中 ===
public final void bindApplication(String processName, ApplicationInfo appInfo,......){
    ....(给data设置各种参数值)
    
    // 发送一个Handler消息
    sendMessage(H.BIND_APPLICATION, data);
}




=== 在ActivityThread.java中的内部类H中 ===
class H extends Handler {

    public static final int BIND_APPLICATION        = 110;

    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;
                // 发送了消息之后在这里接收,然后绑定Application
                handleBindApplication(data);
                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                break;
    }

}



=== 在ActivityThread.java中 ===
// 说实话这里比较抽象,如果不查找资料的话,进去容易找不到,不知道看哪里然后出不来
private void handleBindApplication(AppBindData data) {
    // 创建Application
    app = data.info.makeApplication(data.restrictedBackupMode, null);
    // 赋值给本地变量
    mInitialApplication = app;

    // ContentProviders 初始化
    if (!data.restrictedBackupMode) {
        if (!ArrayUtils.isEmpty(data.providers)) {
            installContentProviders(app, data.providers);
        }
    }

    try {
        // 调用Application的onCreate方法
        // (方法点进去是有注释表明这是调用Application的onCreate)
        mInstrumentation.callApplicationOnCreate(app);
    } catch (Exception e) {
        if (!mInstrumentation.onException(app, e)) {
            // 这里也可以看到,抛出的错误信息是无法创建Applicaiton
            throw new RuntimeException(
              "Unable to create application " + app.getClass().getName()
              + ": " + e.toString(), e);
        }
    }
}


==== 这里进入makeApplication()方法看一下 ====
public Application makeApplication(boolean forceDefaultAppClass,Instrumentation instrumentation) {
    // 创建context
    ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
    // 创建Application,并把上下文传入
    app = mActivityThread.mInstrumentation.newApplication(
            cl, appClass, appContext);

    return app;
    
}

==== 这里进入newApplication()方法看一下 ====
public Application newApplication(ClassLoader cl, String className, Context context)
        throws InstantiationException, IllegalAccessException, 
        ClassNotFoundException {
    Application app = getFactory(context.getPackageName())
            .instantiateApplication(cl, className);
    // 这里最终会调用到attachBaseContext,所以这个方法在onCreate方法之前,并且还能拿到Context
    app.attach(context); --> attachBaseContext(context);
    return app;
}

复制代码

Activity启动流程

Application结束后,我们会回到ActivityManagerService.java,回到那个混脸熟的代码块那边去

ActivityManagerService.java

  • 这里就是对Activity,Service,BroadCast的启动
  • Activity的启动会放在LocalService中去
==== ActivityManagerService.java ====
private boolean attachApplicationLocked(@NonNull IApplicationThread thread,....){

    
    // See if the top visible activity is waiting to run in this process...
    if (normalMode) {
        try {
            // 这里虽然调用的方法是attachApplication,但是他确实是Activity相关的
            // mAtmInternal 是 ActivityTaskManagerService中的内部类LocalService
            didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
        } catch (Exception e) {
            Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
            badApp = true;
        }
    }
    
    // 这是Service
    // Find any services that should be running in this process...
    if (!badApp) {
        didSomething |= mServices.attachApplicationLocked(app, processName);
    }

    // 这是Broadcast
    // Check if a next-broadcast receiver is in this process...
    if (!badApp && isPendingBroadcastProcessLocked(pid)) {
        didSomething |= sendPendingBroadcastsLocked(app);
    }

}

复制代码

ActivityTaskManagerService.java
这里是我感觉整个流程最抽象的地方了,感觉需要配合WMS一起理解比较好

  • 这就是一系列调用流程,但是防止找不到就记录下,反正最终会流入ActivityStackSupervisor.java
==== LocalService.java ====
public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
    synchronized (mGlobalLockWithoutBoost) {
        if (Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER)) {
            Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "attachApplication:" + wpc.mName);
        }
        try {
            // 这里会走整个方法
            // 这里没什么说法,就是没什么地方能进去,就走这个方法
            return mRootWindowContainer.attachApplication(wpc);
        } finally {
            Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
        }
    }
}
复制代码

RootWindowContainer.java

==== RootWindowContainer.java ====
boolean attachApplication(WindowProcessController app) throws RemoteException {
    final PooledFunction c = PooledLambda.obtainFunction(
            // 这里继续进入 startActivityForAttachedApplicationIfNeeded
            // 这里也没什么说法,就是看名字像就点进去看了
            RootWindowContainer::startActivityForAttachedApplicationIfNeeded, this,
            PooledLambda.__(ActivityRecord.class), app, stack.topRunningActivity());

}


==== 还是RootWindowContainer.java ====
private boolean startActivityForAttachedApplicationIfNeeded(ActivityRecord r,
        WindowProcessController app, ActivityRecord top) {
    if (r.finishing || !r.okToShowLocked() || !r.visibleIgnoringKeyguard || r.app != null
            || app.mUid != r.info.applicationInfo.uid || !app.mName.equals(r.processName)) {
        return false;
    }

    try {
        // 这里继续进入,会走到ActivityStackSupervisor.java
        if (mStackSupervisor.realStartActivityLocked(r, app, top == r /*andResume*/,
                true /*checkConfig*/)) {
            mTmpBoolean = true;
        }
    } catch (RemoteException e) {
        Slog.w(TAG, "Exception in new application when starting activity "
                + top.intent.getComponent().flattenToShortString(), e);
        mTmpRemoteException = e;
        return true;
    }
    return false;
}
复制代码

ActivityStackSupervisor.java

  • 这里个人感觉这几个点比较重要
  • clientTransaction,牢记这个玩意,因为他会一直一直一直传递下去
  • clientTransaction.addCallback(LaunchActivityItem) 简单理解 用一个List存放LaunchActivityItem
  • clientTransaction.setLifecycleStateRequest(lifecycleItem) 简单理解 存放下一个Activity要到的状态
  • 最终走到ActivityThread的父类 ClientTransactionHandler 发送Handler消息
==== 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);
    
    // 创建初始的LaunchActivityItem,并把intent传入,我们打开Activity使用的Intent也是这个
    // addCallback 就是添加当一个List中去,记住是把LaunchActivityItem添加到List中
    clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),....)

    // 创建一个与Activity生命周期相关的Item
    if (andResume) {
        lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
    } else {
        lifecycleItem = PauseActivityItem.obtain();
    }
    // 设置生命周期过程中,下一步需要到达的哪个生命周期
    clientTransaction.setLifecycleStateRequest(lifecycleItem);

    // mService 是 ActivityTaskManagerService
    // getLifecycleManager() 是 ClientLifecycleManager
    // 记得这个clientTransaction进行了传递,他是有Activity信息的
    mService.getLifecycleManager().scheduleTransaction(clientTransaction);
   
}
复制代码

ClientLifecycleManager.java

===== ClientLifecycleManager.java ====
void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
    final IApplicationThread client = transaction.getClient();
    // 这里又走到ClientTransaction.java中去
    transaction.schedule();
    ...
}
复制代码

ClientTransaction.java

private IApplicationThread mClient;

public void schedule() throws RemoteException {
    // mClient == IApplicationThread
    // IApplicationThread == ApplicationThread == ActivityThread.java
    // 这个this就是上面的clientTransaction
    mClient.scheduleTransaction(this);
}
复制代码

ActivityThread.java

private class ApplicationThread extends IApplicationThread.Stub {
    @Override
    public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
        // 又调用ActivityThread的scheduleTransaction
        // 但是在ActivityThread中找不到这个方法
        // 找不到就看看父类
        // transaction == clientTransaction 继续传递
        ActivityThread.this.scheduleTransaction(transaction);
    }
}
复制代码

ClientTransactionHandler.java

public abstract class ClientTransactionHandler {
    void scheduleTransaction(ClientTransaction transaction) {
        transaction.preExecute(this);
        // 这里发送消息,有回到ActivityThread的Class H 中去了
        // clientTransaction最终是放到了msg.obj中
        sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
    }
}
复制代码

ActivityThread.java

// 这就看做是执行各种生命周期Item的执行器(我是这么理解的)
private final TransactionExecutor mTransactionExecutor = new TransactionExecutor(this);

public void handleMessage(Message msg) {
    case EXECUTE_TRANSACTION:
        // 这里从msg中取出clientTransaction
        final ClientTransaction transaction = (ClientTransaction) msg.obj;
        // 接着execute执行这个clientTransaction
        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();
        }
        // TODO(lifecycler): Recycle locally scheduled transactions.
        break;
}
复制代码

TransactionExecutor.java

==== TransactionExecutor.java ====
public void execute(ClientTransaction transaction) {
    // transaction是啥?,是一直传递过来的clientTransaction
    ...
    // 循环遍历回调请求的所有状态并在适当的时间执行它们
    executeCallbacks(transaction);
    // 转换到最终状态
    executeLifecycleState(transaction);
    mPendingActions.clear();
    if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "End resolving transaction");
}


==== 还是TransactionExecutor.java ====

public void executeCallbacks(ClientTransaction transaction) {
    // transaction是啥?,是一直传递过来的clientTransaction
    // getCallbacks是啥?,把addCallback对应方法,就是拿出存放了LaunchActivityItem的List
    final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
    final int size = callbacks.size();
    // 然后遍历这个List
    for (int i = 0; i < size; ++i) {
        // 那么我们取出的第一个item,不就是LauncherActivityItem了吗
        final ClientTransactionItem item = callbacks.get(i);
        
        if (closestPreExecutionState != UNDEFINED) {
            cycleToPath(r, closestPreExecutionState, transaction);
        }
        // 接着执行LaunchActivityItem的方法
        item.execute(mTransactionHandler, token, mPendingActions);
        item.postExecute(mTransactionHandler, token, mPendingActions);
    }
}


==== 还是TransactionExecutor.java ====
// executeCallbacks 执行完毕后就执行 executeLifecycleState,这个方法比较简单,就先说了
private void executeLifecycleState(ClientTransaction transaction) {
    // 获取开始设置的 需要到达的 状态
    // 从流程来看,现在这个就是 ResumeActivityItem
    final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
    ...
    // 接着就是ResumeActivityItem,最终也就是 Activity.performResume()
    lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
    lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);

}

复制代码

LaunchActivityItem.java

==== LaunchActivityItem.java ====
public void execute(ClientTransactionHandler client, IBinder token,
        PendingTransactionActions pendingActions) {
    Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
    // Activity信息
    ActivityClientRecord r = new ActivityClientRecord(...);
    // client == ClientTransactionHandler == ActivityThread.java
    client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
    Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
复制代码

ActivityThead.java

public Activity handleLaunchActivity(ActivityClientRecord r,...,Intent customIntent){
    // 这里返回拿到一个Activity,说明里面创建了Activity
    final Activity a = performLaunchActivity(r, customIntent);
}


private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    // 创建context
    ContextImpl appContext = createBaseContextForActivity(r);
    Activity activity = null;
    try {
        // 类加载器
        java.lang.ClassLoader cl = appContext.getClassLoader();
        // 反射生成Activity
        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);
        }
    } catch (Exception e) {
        // 报错信息也能看出,这是在创建Activity
        if (!mInstrumentation.onException(activity, e)) {
            throw new RuntimeException(
                "Unable to instantiate activity " + component
                + ": " + e.toString(), e);
        }
    }
    
    ....
    // 绑定各种信息,可以自己进去看一看
    activity.attach(....)
    // 这里我也不知道走哪里,但是不管哪个都是执行 activity.performCreate()生命周期流程开始了
    if (r.isPersistable()) {
        mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
    } else {
        mInstrumentation.callActivityOnCreate(activity, r.state);
    }
    
    // 设置成ON_CREATE
    r.setState(ON_CREATE);
}

复制代码

然后Activity就这样启动了并走到了OnResume方法去了

总结一下

面试问到,说一下点击Launcher的后,App启动流程

  • Launcher进程请求AMS,AMS请求Zygote进程,都是通过Binder通信的,fork出我们的App
  • ActivityThread的main函数为入口,通过AMS实例的代理,帮助我们绑定Applicaiton(细节可自己补充)
  • 绑定完Applicaiton,对Activity对应的生命周期生成对应的item类,然后交给一个执行器去执行,每执行一个item都会调用activity的方法,然后又会推进到下一个生命周期的状态

最后

这只是简单的走一下流程,毕竟FrameWork层的东西,看多几遍感觉还是懵的,但是多看几遍还是会有收获的 而且里面还有很多细节,一些变量,包括和其他系统Service相关的东西,都是需要去想一想的,感觉也挺有意思的。

Supongo que te gusta

Origin juejin.im/post/7074848550290456589
Recomendado
Clasificación