UI绘制过程(一) -- APP如何启动的

源代码是28版本,使用的软件是AS

入口是ActivityThread.main()方法

attachApplication

在main()方法中会调用一个attach方法在这个方法里面会使用一个IActivityMannager去调用一个attachApplication方法,IActivityMannager实际是ActivityManagerService(AMS)的代理类。

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

一、创建Application
1、在AMS的attachApplication方法中,有系统创建APP的pid uid等application所需要的一些属性值。最终通过一个叫IApplicationThread的代理类调用bindApplication。

private void attach(boolean system, long startSeq) {
    sCurrentActivityThread = this;
    mSystemThread = system;
    if (!system) {
        ViewRootImpl.addFirstDrawHandler(new Runnable() {
            @Override
            public void run() {
                ensureJitEnabled();
            }
        });
        android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
                                                UserHandle.myUserId());
        RuntimeInit.setApplicationObject(mAppThread.asBinder());
        final IActivityManager mgr = ActivityManager.getService();
        try {
            //AMS attachApplication
            mgr.attachApplication(mAppThread, startSeq);
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
        //........do something....
}

为什么需要IActivityMannager和IApplicationThread ?因为ActivityThread属于app进程,AMS属于SystemServer进程。两者之间的通信属于跨进程通讯,需要使用Binder跨进程通讯。

2、IApplicationThread 携带AMS给app创建的一些参数,调用ApplicationThread的bindApplication方法,在这个方法中封装AppBindData对象,并通过H.sendMessage发送BIND_APPLICATION handler消息,最后在H处理消息的回调中,调用handleBindApplication(AppBindData)方法。

3、在handleBindApplication方法中会通过这个方法创建一个Application,data.info.makeApplication(); data.info 是一个PackageInfo对象

String appClass = mApplicationInfo.className;
if (forceDefaultAppClass || (appClass == null)) {
    appClass = "android.app.Application";
    //如果没有定义就是用系统的Application
}

try {
    java.lang.ClassLoader cl = getClassLoader();
    if (!mPackageName.equals("android")) {
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
                "initializeJavaContextClassLoader");
        initializeJavaContextClassLoader();
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    }
    //创建上下文对象并把上下文传递给Application
    ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
    app = mActivityThread.mInstrumentation.newApplication(
            cl, appClass, appContext);
    //并把app传给上下文
    appContext.setOuterContext(app);
}

if (instrumentation != null) {       
    try {  
        //调用了application的onCreate方法
        instrumentation.callApplicationOnCreate(app);        
    }       
}                                                                           

如上代码所示,最后通过获取到类名然后反射得到一个Application,并且执行了onCreate方法。

二、启动Activity
在 第一小节中 AMS的attachApplication通过IApplicationThread的最终通过一个叫IApplicationThread的代理类调用bindApplication方法中创建了Application,在这个方法调用之后

thread.bindApplication();

....
doSomething

// See if the top visible activity is waiting to run in this process...
if (normalMode) {
    try {
        //ActivityStackSupervisor 启动Activity的动作基本都和它有关系
        if (mStackSupervisor.attachApplicationLocked(app)) {
            didSomething = true;
        }
    } 
}

1、attachApplicationLocked
在创建app以后程序在AMS的attachApplication 继续往下走,最后会调用ActivityStackSupervisor的attachApplicationLocked方法。这里会去启动一个app的第一个Activity。

boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
    final String processName = app.processName;
  
            stack.getAllRunningVisibleActivitiesLocked(mTmpActivityList);
            //获取到栈顶的activity
            final ActivityRecord top = stack.topRunningActivityLocked();
            final int size = mTmpActivityList.size();
            for (int i = 0; i < size; i++) {
                final ActivityRecord activity = mTmpActivityList.get(i);
                if (activity.app == null && app.uid == activity.info.applicationInfo.uid
                        && processName.equals(activity.processName)) {
                    try {
                        //真正启动Activity的方法
                        if (realStartActivityLocked(activity, app,
                                top == activity /* andResume */, true /* checkConfig */)) {
                            didSomething = true;
                        }
                    } 
                }
            }

    return didSomething;
}

上述代码中会有两层循环,最后调用对比app.uid和processName 找到当前进程的Activity并启动,这里属于推测

2、realStartActivityLocked
通过方法可以看出这里是一个真正启动Activity的方法, startActivity最后也会调用到这个方法。在这个方法中会调用这样一段代码。它会创建一个ClientTransaction 启动Activity相关的一个事务类,然后添加一个回调。然后设置一个ActivityLifecycleItem状态给事务。 最后使用AMS 相关的类启动事务。

//创建一个启动Activity的事务类
// Create activity launch transaction.
final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,
        r.appToken);
//添加一个回调,传入LaunchActivityItem
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, app.repProcState, r.icicle,
        r.persistentState, results, newIntents, mService.isNextTransitionForward(),
        profilerInfo));
// 设置需要的状态,暂时不知道做什么用
// Set desired final state.
final ActivityLifecycleItem lifecycleItem;
if (andResume) {
    lifecycleItem = ResumeActivityItem.obtain(mService.isNextTransitionForward());
} else {
    lifecycleItem = PauseActivityItem.obtain();
}
clientTransaction.setLifecycleStateRequest(lifecycleItem);
//AMS 执行事务
// Schedule transaction.
mService.getLifecycleManager().scheduleTransaction(clientTransaction);

2、scheduleTransaction执行事务
这个方法获取了一个客户端对象IApplicationThread 然后调用了事务的schedule方法(执行)

void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
    // app进程使用到的类
    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();
    }
}

最后回到了app进程调用了ApplicationThread的scheduleTransaction方法

    // mClient是一个app进程的代理类
    public void schedule() throws RemoteException {
        mClient.scheduleTransaction(this);
    }

在ApplicationThread 中会去调用ActivityThread的scheduleTransaction ,ActivityThread会调用父类ClientTransactionHandler的scheduleTransaction方法。

/** Prepare and schedule transaction for execution. */
void scheduleTransaction(ClientTransaction transaction) {
    transaction.preExecute(this);
    sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}

相同的套路发送了消息EXECUTE_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();
    }
    // TODO(lifecycler): Recycle locally scheduled transactions.
    break;

最终会调用两个比较重要的方法

public void execute(ClientTransaction transaction) {
    //执行回调, 联想到AMS 传入给ClientTransaction的一个LaunchActivityItem
    executeCallbacks(transaction);
    //
    executeLifecycleState(transaction);
}
//最后掉用LaunchActivityItem的
item.execute(mTransactionHandler, token, mPendingActions);

在LaunchActivityItem中最后会调用client.handleLaunchActivity 方法, 从上面的分析我们可以知道ClientTransactionHandler其实就是ActivityThread

public void execute(ClientTransactionHandler client, IBinder token,
        PendingTransactionActions pendingActions) {
    Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
    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 */);
    Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}

3、handleLaunchActivity 启动Activity

通过注释可以知道这事启动Activity的核心实现

/**  Core implementation of activity launch. */
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    ActivityInfo aInfo = r.activityInfo;
    if (r.packageInfo == null) {
        r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                Context.CONTEXT_INCLUDE_CODE);
    }
    //获取到组件名字
    ComponentName component = r.intent.getComponent();
    if (component == null) {
        component = r.intent.resolveActivity(
            mInitialApplication.getPackageManager());
        r.intent.setComponent(component);
    }
    if (r.activityInfo.targetActivity != null) {
        component = new ComponentName(r.activityInfo.packageName,
                r.activityInfo.targetActivity);
    }
    ContextImpl appContext = createBaseContextForActivity(r);
    Activity activity = null;
    try {
        //反射创建一个Activity
        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);
        }
    } 
    try {
        //
        Application app = r.packageInfo.makeApplication(false, mInstrumentation);
      
        if (activity != null) {
            CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
            Configuration config = new Configuration(mCompatConfiguration);
            if (r.overrideConfig != null) {
                config.updateFrom(r.overrideConfig);
            }
            
            Window window = null;
            if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
                window = r.mPendingRemoveWindow;
                r.mPendingRemoveWindow = null;
                r.mPendingRemoveWindowManager = null;
            }
            appContext.setOuterContext(activity);
            //1、 调用activity的attach方法  在这个方法里面会去创建window相关的东西,意思就是讲Activity与PhoneWindow关联起来  PWS
            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 (customIntent != null) {
                activity.mIntent = customIntent;
            }
            r.lastNonConfigurationInstances = null;
            checkAndBlockForNetworkAccess();
            activity.mStartedActivity = false;
            //设置主题
            int theme = r.activityInfo.getThemeResource();
            if (theme != 0) {
                activity.setTheme(theme);
            }
            activity.mCalled = false;
            //调用onCreate
            if (r.isPersistable()) {
                mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
            } else {
                mInstrumentation.callActivityOnCreate(activity, r.state);
            }
            r.activity = activity;
        }
        //设置状态
        r.setState(ON_CREATE);
        mActivities.put(r.token, r);
    }
    return activity;
}

调用onCreate方法

public void callActivityOnCreate(Activity activity, Bundle icicle,
        PersistableBundle persistentState) {
    prePerformCreate(activity);
    activity.performCreate(icicle, persistentState);
    postPerformCreate(activity);
}

小结一下

通过上面的分析最后我们创建的Application 和Activity 我们的应用启动了。 首先是在ActivityThread 的main方法中通过binder通信调用AMS的获取Application需要的一些参数,这里应该叫做分配pid uid等一些属性信息。 然后在调用IApplicationThread 创建出Application ,并执行onCreate和上下文的绑定操作。AMS在创建好了application以后调用ActivityStackSupervisor去启动Activity,同样是使用IApplicationThread去发送消息,并使用反射创建Activity。但是在这中间有个事务类ClientTransaction 它会创建一个回调,然后在执行消息时,通过LaunchActivityItem实例去启动Activity。

何时调用onStart onResume方法呢? 下一篇博客讲继续往下分析。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值