Android进阶解密读书笔记(四)——四大组件的启动过程

根 Activity 的启动过程

Activity 的启动分为两种,一种是根 Activity 的启动过程,另一种是普通 Activity 的启动过程。根 Activity 指的是应用程序启动的第一个 Activity,因此根 Activity 的启动过程一般情况下也可以理解为应用程序的启动过程。普通Activity 指的是除应用程序启动的第一个 Activity 之外的其他 Activity。根 Activity 的启动过程分为3个部分:Launcher 请求 AMS 过程、AMS 到 ApplicationThread 的调用过程和 ActivityThread 启动 Acitivity

Launcher请求 AMS 过程

Launcher 启动后会将已安装的应用程序快捷图标显示到桌面上,这些应用程序的快捷图标就是启动根 Activity 的入口。整个时序流程如下:

Launcher.startActivitySafely() -> Activity.startActivity() -> Activity.startActivityForResult() -> Instrumentation.execStartActivity() -> ActivityManager.startActivity() -> IActivityManager.startActivity() -> AMS

  1. Launcher.startActivitySafely()

    ( /packages/apps/Launcher3/src/com/android/launcher3/Launcher.java)

    1. intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK): 将 FLAG 设置为 Intent.FLAG_ACTIVITY_NEW_TASK,这样根 Activity 会在新的任务栈中启动

    2. startActivity(intent, opsBundle): 调用 startActivity 这个方法,该方法在 Activity 中实现

  2. Activity.startActivity()

    在 statrActivity() 方法中会调用 startActivityForResult() 方法,它的第二个参数为 -1,表示 Launcher 不需要知道 Activity 启动的结果

  3. Activity.startActivityForResult()

    1. if(mParent == null){}: mParent 是 Activity 类型的,表示当前 Activity 的父类。因为目前根 Activity 还没有创建出来,因此 mParent == null 成立。接着调用 Instrumentation 的 execStartActivity 方法,Instrumentation 主要用来监控应用程序和系统的交互

  4. Instrumentation.execStartActivity()

    1. int result = ActivityManager.getService() //获取 AMS 的代理对象

      .startActivity(....); //调用 startActivity 方法(最终调用的是AMS的startActivity方法)

  5. ActivityManager.getService() 

//getServices方法调用了 IActivityManagerSingleton 的 get 方法
public static IActivityManager getService(){
  return IActivityManagerSingleton.get();
}

private static final Singleton IActivityManagerSingleton = new Singleton(){
     @Override
     protected IActivityManager create(){
         //得到名为"activity"的 Service引用,也就是IBinder类型的 AMS 的引用
         final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
         //将它转换成 IActivityManager 类型的对象(这段代码采用的是 AIDL)
         final IActivityManager am = IActivityManager.Stub.asInterface(b);
         return am;
     }
}

IActivityManager.java类是由AIDL工具在编译时自动生成的(frameworks/base/cpre/java/android/app/IActivityManager.aidl)。要实现进程间通信,AMS也就是服务器端只需要继承 IActivityManager.Stub 类并实现相应的方法就可以了

AMS 到 ApplicationThread 的调用过程

ActivityManagerService.java

Launcher 请求 AMS 后,代码逻辑已经进入 AMS 中

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

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(..., UserHandler.getCallingUserId());
}

//startActivityAsUser()方法比startActivity方法多了一个参数 UserHandler.getCallingUserId(),这个方法会获得调用者的 UserId ,AMS根据这个 UserId 来确定调用者的权限
public final int startActivityAsUser(..., int userId){
    //判断调用者是否被隔离,如果被隔离则抛出 SecurityException 异常
    enforceNotIsolatedCaller("startActivity");
    //检查调用者权限,如果没有权限也会抛出 SecurityException 异常
    userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, false, ALLOW_FULL_ONLY, "startActivity", null);
    
    return mActivityStarter.startActivityMayWait(...,null, "startActivityAsUser");
}

ActivityStarter

ActivityStarter 是 Android7.0 中新加入的类,它是加载 Activity 的控制类,会收集所有的逻辑来决定如何将 Intent 和 Flags 转换为 Activity ,并将 Activity 和 Task 以及 Stack 相关联

frameworks/base/services/core/java/com/android/server/am/ActivityStarter.java

//inTask:是TaskRecord类型,代表启动的 Activity 所在的栈
//reason:是String类型,代表启动的理由
final int stratActivityMayWait(..., TaskRecord inTask, String reason){
    ...
    int res = startActivityLocked(...);
    ...
    return res;
}

int startActivityLocked(..., String reason){
    //判断启动的理由不为空
    if(TextUtils.isEmpty(reason)){
        throw new IllegalArgumentException("Need to specify a reason.");
    }
    
    ...
    mLastStartActivityResult = startActivity(...);
}

private int startActivity(IApplicationThread caller, ...){
    //caller指向的是Launcher所在的应用程序的 ApplicationThread 对象
    if(caller != null){
        //得到Launcher进程:调用 AMS 的 getRecordForAppLocked 方法得到一个代表 Launcher 进程的 callerApp对象
        callerApp = mService.getRecordForAppLocked(caller);
    }
    
    //创建即将要启动的 Activity 的描述类 ActivityRecord
    //ActivityRecord用于描述一个 Activity,用来记录一个Activity的所有信息
    ActivityRecord r = new ActivtiyRecord(...);
    if(outAcitivity != null){
        //将创建的 ActivityRecord 赋值给 ActivityRecord[] 类型的 outActivity,这个outActivity会作为参数传递下去
        outActivity[0] = r;
    }
    ...
    return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true, options, inTask, outActivity);
}

private int startActivity(...){
    try{
        mService.mWindowManager.deferSurfaceLayout();
        result = startActivityUnchecked(...);
    }
    ...
    return result;
}

//主要处理与栈管理相关的逻辑
private int startActivityUnchecked(...){
    ...
    //之前我们设置的 mLauncher 为 FLAG_ACTIVITY_NEW_TASK
    if(mStartActivity.resultTo == null && mInTask == null && !mAddingToTask
          && (mLauncherFlags & FLAG_ACTIVITY_NEW_TASK) != 0){
        nweTask = true;
        //创建新的 TaskRecord,用来描述一个 Activity 任务栈,也就是说 setTaskFromReuseOrCreateNewTask 方法内部会创建一个新的 Activity 任务栈
        result = setTaskFromReuseOrCreateNewTask(taskToAffiliate, preferredLaunchStackId, topStack);
    }
    ...
    //调用 ActivityStackSupervisor的resumeFocusedStackTopActivityLocked 方法
    mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity, mOptions);
}

ActivityStackSupervisor.java

frameworks/base/services/core/java/com/android/server/am/ActivityStackSupervisor.java

boolean resumeFocusedStackTopActivityLocked(ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions){
    ...
    //获取要启动的Activity所在栈的栈顶的不是处于停止状态的ActivityRecord
    final ActivityRecord r = mFocusedStack.topRunningActivityLocked();
    
    //ActivityRecord 不为null,或者要启动的 Activity 的状态不是 RESUMED 状态
    if(r == null || r.state != RESUMED){
        //调用ActivityStack的方法
        mFocusedStack.resumeTopActivityUncheckedLocked(null, null);
    }
}

ActivityStack.java
boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options){
    ...
    result = resumeTopActivityInnerLocked(prev, options);
    ...
    return result;
}

//该方法的代码非常多,我们只需要关注调用了 ActivityStackSupervisor 的 startSpecificActivityLocked方法就可以
private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options){
    ...
    mStackSupervisor.startSpecificActivityLocked(next, true, true);
}

ActivityStackSupervisor.java
void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig){
    //获取即将启动的Activity所在的应用程序进程
    ProcessRecord app = mService.getProcessRecordLocked(r.processName, r.info.applicationInfo.uid, true);
    
    //判断要启动的 Activity 所在的应用程序进程是否已经运行
    if(app != null && app.thread != null){
        ...
        //第二个参数代表要启动的 Activity 所在的应用程序进程的 ProcessRecord
        realStartActivityLocked(r, app, andResume, checkConfig);
    }
}

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, new Configuration(mService.mConfiguration), new Configuration(task.mOverrideConfig), r.compat, r.launchedFromPackage, task.voiceInteractor, app.repProcState, r.icicle, r.persistentState, results, newIntents, !andResume, mService.isNextTransitionForward(), profilerInfo);
}

app.thread 指的是 IApplicationThread,它的实现是 ActivityThread 的内部类 ApplicationThread, 其中 ApplicationThread 继承了 IApplicationThread.Stub。 app指的是传入的要启动的 Activity 所在的应用程序进程。因此realStartActivityLocked中的代码是要在目标应用程序进程启动 Activity。当前的代码逻辑运行在 AMS 所在的进程(SystemServer 进程)中,通过 ApplicationThread 来与应用程序进程进行 Binder 通信,换句话说 ApplicationThread 是 AMS 所在进程(SystemServer 进程)和应用程序进程的通信桥梁

ActivityThread 启动 Acitivity 的过程

启动流程

ActivityThread.java

scheduleLaunchActivity() -> sendMessage()

H.java

handleMessage() -> handleLaunchActivity()

ActivityThread.java

performLaunchActivity -> callActivityOnCreate()

Instrumentation.java

performCreate()

Activity.java

onCreate()

在整个流程中我们最主要的是关注 performLauncherActivity() 这个方法,具体的实现可以去阅读源码

(ps:只是看了Activity的启动流程就有点想放弃了,所以跳过本章后面的内容,直接阅读下一章节,后面再来和本章战斗)

你可能感兴趣的:(Android进阶解密读书笔记,android,java,apache)