(Android11.0)App启动过程的深度挖掘(下篇)

Posted 丶笑看退场

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了(Android11.0)App启动过程的深度挖掘(下篇)相关的知识,希望对你有一定的参考价值。

前文说到,Activity启动过程在ATMS中绕了一大圈,最终还是通过调用ClientTransactionschedule方法,回到了ApplicationThread中。那我们就接着往下看启动过程。

ActivityThread启动Activity

我们来看下ApplicadtionThreadscheduleTransaction方法:

### ActivityThread/ApplicationThread
  public void scheduleTransaction(ClientTransaction transaction) throws RemoteException 
            ActivityThread.this.scheduleTransaction(transaction);
        

实际上最终实现调用的是在ActivityThread的父类ClientTransactionHandler中:

### ClientTransactionHandler 
void scheduleTransaction(ClientTransaction transaction) 
        transaction.preExecute(this);
        sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
    

方法很简单,就是发送一个启动消息交由Handler处理,这个handler有着一个很简单的名字:H。在这里地调用了sendMessage方法向H类发送类型为EXECUTE_TRANSACTION消息,sendMessage方法如下所示:

### ActivityThread
private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) 
        if (DEBUG_MESSAGES) 
            Slog.v(TAG,
                    "SCHEDULE " + what + " " + mH.codeToString(what) + ": " + arg1 + " / " + obj);
        
        Message msg = Message.obtain();
        msg.what = what;
        msg.obj = obj;
        msg.arg1 = arg1;
        msg.arg2 = arg2;
        if (async) 
            msg.setAsynchronous(true);
        
        mH.sendMessage(msg);
    

这里mH指的是H,它是ActivityThread的内部类并继承Handler,是应用程序进程中主线程的消息管理类

再想下这个消息是从哪里发送出来的? 我们知道,服务器的Binder方法运行在Binder的线程池中,也就是说系统进行跨进程调用ApplicationThread的scheduleTransaction就是执行在Binder的线程池中的了。

接着来看下Handler H对消息的处理,如下所示:

### ActivityThread
final H mH = new H();

class H extends Handler 
        public static final int BIND_APPLICATION        = 110;
       ......
        public static final int EXECUTE_TRANSACTION = 159;
        public static final int RELAUNCH_ACTIVITY = 160;

       ......
         
        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;
                case EXIT_APPLICATION:
                    if (mInitialApplication != null) 
                        mInitialApplication.onTerminate();
                    
                    Looper.myLooper().quit();
                    break;
                
               .......
                 
                case EXECUTE_TRANSACTION:
                    final ClientTransaction transaction = (ClientTransaction) msg.obj;
                    mTransactionExecutor.execute(transaction);
                    if (isSystem()) 
                        //系统进程内的客户端事务在客户端而不是 ClientLifecycleManager 被回收,以避免在处理此消息之前被清除。
                        transaction.recycle();
                    
                    // 回收本地预定的事务。
                    break;
                case RELAUNCH_ACTIVITY:
                    handleRelaunchActivityLocally((IBinder) msg.obj);
                    break;
                .......
            
            .......
        
    

查看H的handleMessage方法中对EXECUTE_TRANSACTION的处理。取出ClentTransaction实例,调用execute方法。

### TransactionExector
public void execute(ClientTransaction transaction) 
        if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Start resolving transaction");

        final IBinder token = transaction.getActivityToken();
       
        ......

        executeCallbacks(transaction);

        executeLifecycleState(transaction);
        mPendingActions.clear();
        if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "End resolving transaction");
    

接着来看executeCallbacks方法:

### TransactionExector
      public void executeCallbacks(ClientTransaction transaction) 
        final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
        ......

        final int size = callbacks.size();
        for (int i = 0; i < size; ++i) 
            final ClientTransactionItem item = callbacks.get(i);
            if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "Resolving callback: " + item);
            final int postExecutionState = item.getPostExecutionState();
            final int closestPreExecutionState = mHelper.getClosestPreExecutionState(r,
                    item.getPostExecutionState());
            if (closestPreExecutionState != UNDEFINED) 
                cycleToPath(r, closestPreExecutionState, transaction);
            

          //关键代码
            item.execute(mTransactionHandler, token, mPendingActions);
            item.postExecute(mTransactionHandler, token, mPendingActions);
            if (r == null) 
                // Launch activity request will create an activity record.
                r = mTransactionHandler.getActivityClient(token);
            

           ......
        
    

可以看到遍历了Callbacks,调用了execute方法。那这里的item又是什么?

### ActivityStackSupervisor.realStartActivityLocked
clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
                        System.identityHashCode(r), r.info,
                        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()));

从上篇文章知道,放入callbacks里的其实是ClientTransactionItem的子类LaunchActivityItem,所以我们关注下launchActivityItem中的execute方法。

### launchActivityItem
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, mAssistToken, mFixedRotationAdjustments);
        client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    

这里ClientTransactionHandlerActivityThread的父类。又将启动Activity的参数封装成ActivityClientRecord,最后调用了handleLaunchActivity方法。

Activity启动核心实现

下面开始启动过程代码基本android7.0,8.0,9.0,10.0一样

### ActivityThread
      public Activity handleLaunchActivity(ActivityClientRecord r,
            PendingTransactionActions pendingActions, Intent customIntent) 
      
        ......

        // 在创建活动之前初始化
        if (!ThreadedRenderer.sRendererDisabled
                && (r.activityInfo.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0) 
            HardwareRenderer.preload();
        
        WindowManagerGlobal.initialize();

        GraphicsEnvironment.hintActivityLaunch();

  			//启动Activity
        final Activity a = performLaunchActivity(r, customIntent);

        if (a != null) 
            r.createdConfig = new Configuration(mConfiguration);
            reportSizeConfigurations(r);
            if (!r.activity.mFinished && pendingActions != null) 
                pendingActions.setOldState(r.state);
                pendingActions.setRestoreInstanceState(true);
                pendingActions.setCallOnPostCreate(true);
            
         else 
            try 
              //停止Activity启动
                ActivityTaskManager.getService()
                        .finishActivity(r.token, Activity.RESULT_CANCELED, null,
                                Activity.DONT_FINISH_TASK_WITH_ACTIVITY);
             catch (RemoteException ex) 
                throw ex.rethrowFromSystemServer();
            
        

        return a;
    

performLaunchActivity方法最终完成了Activity对象的创建和启动过程。我们再来看下performActivity方法做了什么。

### ActivityThread
//核心实现
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) 
  			//从ActivityClientRecord中后去待启动的Activity的组件信息
        ActivityInfo aInfo = r.activityInfo;
        if (r.packageInfo == null) 
          //获取APK文件的描述类LoadedApk
            r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
                    Context.CONTEXT_INCLUDE_CODE);
        

  			//ComponentName类中保存了该Activity的包名和类名
        ComponentName component = r.intent.getComponent();  
        ......

  			//创建要启动Activity的上下文环境
        //Context中的大部分逻辑都是由ContextImpl来完成
        ContextImpl appContext = createBaseContextForActivity(r);  
  
  		//通过Instrumentation的newActivity方法使用类加载创建Activity对象。
        Activity activity = null;
        try 
            java.lang.ClassLoader cl = appContext.getClassLoader();
          //根据ComponentName中存储的Activity类名,用类加载器来创建该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) 
            if (!mInstrumentation.onException(activity, e)) 
                throw new RuntimeException(
                    "Unable to instantiate activity " + component
                    + ": " + e.toString(), e);
            
        

        try 
          //创建Application,makeApplication方法内部会调用Application的onCreate方法
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);   //注释1

            .......

            if (activity != null) 
                .......
                Window window = null;
                if (r.mPendingRemoveWindow != null && r.mPreserveWindow) 
                    window = r.mPendingRemoveWindow;
                    r.mPendingRemoveWindow = null;
                    r.mPendingRemoveWindowManager = null;
                

                // 必须使用与应用程序上下文相同的加载器来初始化活动资源。
                appContext.getResources().addLoaders(
                        app.getResources().getLoaders().toArray(new ResourcesLoader[0]));

                appContext.setOuterContext(activity);
              	// 初始化Activity
                //attach方法中会创建Window对象(PhoneWindow)并与Activity自身进行关联。
                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 (customIntent != null) 
                    activity.mIntent = customIntent;
                
                r.lastNonConfigurationInstances = null;
                checkAndBlockForNetworkAccess();
                activity.mStartedActivity = false;
                .......
                  
                activity.mCalled = false;
                if (r.isPersistable()) 
                  //调用Instrumentation的callActivityOnCreate方法来启动Activity
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);      //注释2
                 else 
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                
               .......
                 
                r.activity = activity;
                mLastReportedWindowingMode.put(activity.getActivityToken(),
                        config.windowConfiguration.getWindowingMode());
            
            r.setState(ON_CREATE);
            synchronized (mResourcesManager) 
                mActivities.put(r.token, r);
            

         catch (SuperNotCalledException e) 
            throw e;

         
 			 ........

        return activity;
    

再来看下注释1 处,Application是怎么被创建出来的? makeApplication方法,如下所示:

### LoadApk  
public Application makeApplication(boolean forceDefaultAppClass,
            Instrumentation instrumentation) 
        if (mApplication != null) 
            return mApplication;
        
        .......
          
       Application app = null;

       String appClass = mApplicationInfo.className;
  			if (forceDefaultAppClass || (appClass == null)) 
            appClass = "android.app.Application";
        
       .......
       
        try 
            final java.lang.ClassLoader以上是关于(Android11.0)App启动过程的深度挖掘(下篇)的主要内容,如果未能解决你的问题,请参考以下文章

(Android11.0)App启动过程的深度挖掘(下篇)

(Android11.0)Android启动过程的深度挖掘(上篇)

阿里大佬首次分享《Android11.0最新Framework解析》限时免费下载高清PDF文档

阿里大佬首次分享《Android11.0最新Framework解析》限时免费下载高清PDF文档

[转-备忘]iOS11.0后APP的图标和启动图

Android 10.0 11.0 12.0 启动模拟器教程