Activity 启动流程


关注启动流程中的时机
1,Activity 创建
2,Application 创建
3,ContextImpl 初始化
4,attach() 方法
5,生命周期
6,窗体和管理器创建
7,布局初始化
8,窗体添加视图

一、启动方法

通过 Activity 的类名,显式启动,定义一个 Intent。

Intent intent = new Intent(this, XxxActivity);
startActivity(intent);

startActivity() 方法重载,最后调用 Activity 类 startActivityForResult() 方法,Intent 类封装启动意图,包含被启动对象的信息和数据。

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

Instrumentation 对象的 execStartActivity() 方法,实现 App 插件化时,可以 hook 该对象,拦截替换要启动的类名。

public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, Activity target,
        Intent intent, int requestCode, Bundle options) {
    ...
    try {
        int result = ActivityManager.getService()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);
        checkStartActivityResult(result, intent);
    } catch (RemoteException e) {
        throw new RuntimeException("Failure from system", e);
    }
    return null;
}

ActivityManager 类 getService() 方法,获取 system_sever 进程 Ams 服务在本地的 binder 代理 IActivityManager。
通过代理的 startActivity()方法 ,进入Ams服务,请求参数 Bundle、IApplicationThread、Intent、requestCode 等,向 Ams 注册 Activity 组件。

Activity 启动流程_第1张图片
ActivityThread 类和 Ams 服务的关系

1,ApplicationThread,ActivityThread 内部类,定义 Ams 服务回调 App 进程的业务接口,如 Activity 和 Service 启动/停止功能。
2,Context who.getBasePackageName(),当前发起者上下文包名,例如从 A 启动 B 组件时,who 是 A。
3,IBinder token,当前发起者内部 IBinder 对象,在组件启动的 attach() 方法赋值,通知 Ams 服务,发起者是谁,例如,当 Ams 服务回调 App 通知发起者暂停时,通过回传 App 进程的 token,可以查找执行暂停的组件。
在 Ams 服务,ActivityRecord 类记录 token,标识客户端一个 Activity 组件。

二、Ams 服务流程

跨进程调用 Ams 服务,即将组件 注册到 Ams,负责管理 Activity 栈结构。

Ams 服务流程( Activity 启动)

三、App 本地流程

客户端代理 IApplicationThread ,ApplicationThread 类的 scheduleTransaction() 方法。

@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
    ActivityThread.this.scheduleTransaction(transaction);
}

ActivityThread 的 this 方法在父类中,即继承 ClientTransactionHandler 类。

void scheduleTransaction(ClientTransaction transaction) {
        transaction.preExecute(this);
    sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}

ActivityThread 内部类 H 接收 EXECUTE_TRANSACTION 消息。

case EXECUTE_TRANSACTION:
    final ClientTransaction transaction = (ClientTransaction) msg.obj;
    mTransactionExecutor.execute(transaction);  
    ...
break;

TransactionExecutor 类的 execute() 方法,处理事务,参数 ClientTransaction 来自 Ams 服务。

public void execute(ClientTransaction transaction) {
    final IBinder token = transaction.getActivityToken();
    executeCallbacks(transaction); //处理LaunchActivityItem
    executeLifecycleState(transaction);//处理ResumeActivityItem
}
Activity 启动流程_第2张图片
ClientTransaction 的 LaunchActivityItem 和 ResumeActivityItem

由 TransactionExecutor 类 execute() 方法 开始生命周期==>>

1,executeCallbacks() ==>> LaunchActivityItem execute()执行,ActivityThread 类 handleLaunchActivity() 方法 ==>onCreate()。

2,executeLifecycleState() ==>> cycleToPath()==>>ActivityThread 类handleStartActivity() 方法 ==>>onStart()。

3,executeLifecycleState() ==>> ResumeActivityItem execute()方法,ActivityThread 类 handleResumeActivity() 方法 ==>>onResume()。

LaunchActivityItem 类 execute() 方法。

@Override
public void execute(ClientTransactionHandler client, IBinder token,
                    PendingTransactionActions pendingActions) {
    //client即ActivityThread类
    ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
            mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
            mPendingResults, mPendingNewIntents, mIsForward,
            mProfilerInfo, client);
    client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
}

创建 ActivityClientRecord 本地记录,封装 Ams 回调数据,token 字段是在 Ams服务中 ActivityRecord 记录保存的唯一 appToken 标志。

ResumeActivityItem 类 execute()方法。

@Override
public void execute(ClientTransactionHandler client, IBinder token,
                    PendingTransactionActions pendingActions) {
    client.handleResumeActivity(token, true /* finalStateRequest */, mIsForward,
            "RESUME_ACTIVITY");
}

client 即 ActivityThread 类,三个方法。

handleLaunchActivity(),
handleStartActivity(),
handleResumeActivity()。

Activity 启动流程_第3张图片
Activity 启动本地流程图

1,handleLaunchActivity() 方法。

@Override
public Activity handleLaunchActivity(ActivityClientRecord r,
                                     PendingTransactionActions pendingActions, Intent customIntent) {
    ...
    handleConfigurationChanged(null, null);
    //WindowManagerGlobal 初始化
    WindowManagerGlobal.initialize();
    //返回Activity对象
    final Activity a = performLaunchActivity(r, customIntent);
    if (a != null) {
        ...
    } else {
        try {
            //Activity对象未成功创建,通知Ams结束Activity的启动
            ActivityManager.getService()
                    .finishActivity(r.token, Activity.RESULT_CANCELED, null,
                            Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
        } catch (RemoteException ex) {
        }
    }
    return a;
}

ActivityThread 类 performLaunchActivity() 方法。


private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    //ActivityClientRecord封装的是Ams传来的信息。
    //获取本地记录ActivityClientRecord的ActivityInfo。
    ActivityInfo aInfo = r.activityInfo;
    if (r.packageInfo == null) {
        r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                Context.CONTEXT_INCLUDE_CODE);
    }
    //从Intent,获取组件Name,ComponentName
    ComponentName component = r.intent.getComponent();
    ...
    //创建ContextImpl对象,赋值给Activity
    ContextImpl appContext = createBaseContextForActivity(r);
    Activity activity = null;
    try {
        java.lang.ClassLoader cl = appContext.getClassLoader();
        //创建Activity实例 
        activity = mInstrumentation.newActivity(
                cl, component.getClassName(), r.intent);
    } catch (Exception e) {
    }
    try {
        //创建Application对象,赋值给Activity
        Application app = r.packageInfo.makeApplication(false, mInstrumentation);
        if (activity != null) {
            ...
            appContext.setOuterContext(activity);
            //执行Activity的attach方法
            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);
            if (r.isPersistable()) {
                //触发生命周期方法onCreate
                mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
            } else {
                mInstrumentation.callActivityOnCreate(activity, r.state);
            }
            r.activity = activity;
        }
        //绑定IBinder类型的token和ActivityClientRecord
        //Map数组
        //token 和本地记录保存在 Map 中,当 Ams 服务回调 App 进程的某个组件时,
        //根据 token 从 Map 中获取本地 ActivityClientRecord 从而定位到组件。
        mActivities.put(r.token, r);
    }  catch (Exception e) {
    }
    return activity;
}

该方法负责组件实例创建,生命周期方法开始。

Activity 组件创建

Activity 生命周期

在生命周期 onCreate() 方法,调用 setContentView() 方法,初始化 UI 布局。
setContentView() 初始化

初始化顶层视图 DecorView,PhoneWindow 窗体对象内部 mDecor 变量,根据布局资源 layout resId,解析视图对象,ViewGroup 类 addView() 方法添加,以顶层视图为根节点,构建树形结构。

2,handleStartActivity() 方法。

@Override
public void handleStartActivity(ActivityClientRecord r,
                                PendingTransactionActions pendingActions) {
    final Activity activity = r.activity;
    //activity是空,r状态是stop,activiity是mFinished,直接退出。
    //触发生命周期方法onStart()。
    activity.performStart("handleStartActivity");
    //触发Activity的onRestoreInstanceState方法
    if (pendingActions.shouldRestoreInstanceState()) {
        if (r.isPersistable()) {
            if (r.state != null || r.persistentState != null) {
                mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
                        r.persistentState);
            }
        } else if (r.state != null) {
            mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
        }
    }
    //触发Activity的onPostCreate方法
    ...
}

生命周期 onStart() 方法,必要时,执行 OnRestoreInstanceState()。

3,handleResumeActivity() 方法。

@Override
public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
                                 String reason) {
    //生命周期onResume()方法
    final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
    final Activity a = r.activity;
    boolean willBeVisible = !a.mStartedActivity;
    if (r.window == null && !a.mFinished && willBeVisible) {
        //在attach()方法,已经为Activity创建了Window
        r.window = r.activity.getWindow();
        View decor = r.window.getDecorView();
        //此时DecorView不可见
        decor.setVisibility(View.INVISIBLE);
        ViewManager wm = a.getWindowManager();
        WindowManager.LayoutParams l = r.window.getAttributes();
        a.mDecor = decor;
        ...
        if (a.mVisibleFromClient) {
            if (!a.mWindowAdded) {
                a.mWindowAdded = true;
                //绑定View
                wm.addView(decor, l);
            } else {
                a.onWindowAttributesChanged(l);
            }
        }
    } else if (!willBeVisible) {
    }
    if (!r.activity.mFinished && willBeVisible && r.activity.mDecor != null && !r.hideForNow) {
        ...
        if (r.activity.mVisibleFromClient) {
            //让DecorView可见,即调用DecorView的setVisibility(View.VISIBLE)
            r.activity.makeVisible();
        }
    }
}

生命周期 onResume() 方法,组件可视化,组件绑定窗体和视图。

组件 Add Window 和 View
Window addView 视图
WindowManager 类 addView() 方法,
调用本地 WindowManagerImpl 类的 addView() 方法。

四、总结

框架层主要方法汇总:
1,createBaseContextForActivity(),创建 ContextImpl 。
2,Instrumentation # newActivity(),创建 Activity 实例。
3,LoadedApk # makeApplication(),首次创建 Application。
4,Activity # attach() ,赋值,窗体初始化,窗体管理器。
5,Instrumentation # callActivityOnCreate(),初始化 DecorView。
6,Activity # performStart(),开始活动。
7,Activity # performResume(),
8,WindowManager # addView(),


任重而道远

你可能感兴趣的:(Activity 启动流程)