浅析ActivityThread#main()方法和生命周期事务处理(代码基于Android-12)

浅析ActivityThread#main()方法和生命周期事务处理(代码基于Android-12

问题:

ActivityApplicationonCreate()在哪被调用的?

ContentProvider为什么比Application先创建?

Activity#attach()在哪里被调用的?

Activity事务处理器H处理了哪些消息?
为什么onCreate()onResume()获取不到View的宽高嘞?

文章目录哟

一、解析应用程序入口函数Activity#main()

在文章当我点击桌面App的图标时发生了什么-浅析Activity启动流程(代码基于Android-12)中我们提到了Activity#main()何时被调用的,以及在走完main()之后又发送了LauncherActivityItem事务和ResumeActivityItem生命周期请求,接着调用远程IApplicationThread.aidl接口实现类ApplicationThread#scheduleTransaction()方法处理刚刚俩个事务请求。

1.1 ClientLifecycleManager#sheduleTransaction()

    /**
     * Schedule a transaction, which may consist of multiple callbacks and a lifecycle request.
     * @param transaction A sequence of client transaction items.
     * @throws RemoteException
     *
     * @see ClientTransaction
     */
    void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
        // 设置 mClient, mClient是通过WindowProcessController获取到的IApplicationThread.aidl实现类-ApplicationThread(ActivityThread的内部类)
        final IApplicationThread client = transaction.getClient();
        // 也就是调用ApplicationThread#schedule(),阅读到这里,最好是看下ActivityThread.main()方法干了什么
        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();
        }
    }

那么ApplicationThread到底是什么?shedule了什么捏?

这就必须从ActivityThread#main()方法说起了!

1.2 main(),你搞了什么?

1.2.1 ActivityThread#main()

准备Loopper;

ApplicationThread对象存入AMS中以便完成各种通讯

Loopper开始轮询处理消息 - [提出问题:为什么loop()死循环不会阻塞主线程嘞?]

public static void main(String[] args) {
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
        // Install selective syscall interception
        AndroidOs.install();
        // CloseGuard defaults to true and can be quite spammy.  We
        // disable it here, but selectively enable it later (via
        // StrictMode) on debug builds, but using DropBox, not logs.
        CloseGuard.setEnabled(false);
        Environment.initForCurrentUser();
        // Make sure TrustedCertificateStore looks in the right place for CA certificates
        final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
        TrustedCertificateStore.setDefaultUserDirectory(configDir);
        // Call per-process mainline module initialization.
        initializeMainlineModules();
        Process.setArgV0("<pre-initialized>");

    	// 1.创建主线程(也叫UI线程)Loopper
        Looper.prepareMainLooper();
    
        // Find the value for {@link #PROC_START_SEQ_IDENT} if provided on the command line.
        // It will be in the format "seq=114"
        long startSeq = 0;
        if (args != null) {
            for (int i = args.length - 1; i >= 0; --i) {
                if (args[i] != null && args[i].startsWith(PROC_START_SEQ_IDENT)) {
                    startSeq = Long.parseLong(
                            args[i].substring(PROC_START_SEQ_IDENT.length()));
                }
            }
        }

    	// 2.创建ActivityThread对象并执行attach()方法将ApplicationThread实例传入AMS
        ActivityThread thread = new ActivityThread();
        thread.attach(false, startSeq);

    	// 3.创建事务处理Handler类-H.java实例
        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }

        if (false) {
            Looper.myLooper().setMessageLogging(new
                    LogPrinter(Log.DEBUG, "ActivityThread"));
        }

        // End of event ActivityThreadMain.
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    
    	// 主线程Loopper开始轮询让H处理各种Message
        Looper.loop();

    	// 如果轮询意外终止,抛出异常
        throw new RuntimeException("Main thread loop unexpectedly exited");
    }

1.2.2 ActivityThread#attach()

ActivityThread对象创建之后,立马执行其attach()方法

// system参数为false,非系统应用
@UnsupportedAppUsage
private void attach(boolean system, long startSeq) {
    sCurrentActivityThread = this;
    mConfigurationController = new ConfigurationController(this);
    mSystemThread = system;
    if (!system) {
        android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
                UserHandle.myUserId());
        RuntimeInit.setApplicationObject(mAppThread.asBinder());
        
        // 获取AMS,AMS是IActivityManager.aidl实现类
        final IActivityManager mgr = ActivityManager.getService();
        try {
            // 将mAppThread(ApplicationThread对象)存入AMS中
            // mAppThread是成员变量,是在声明的时候new出来的
            mgr.attachApplication(mAppThread, startSeq);
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
        // Watch for getting close to heap limit.
        BinderInternal.addGcWatcher(new Runnable() {
            @Override public void run() {
                if (!mSomeActivitiesChanged) {
                    return;
                }
                Runtime runtime = Runtime.getRuntime();
                long dalvikMax = runtime.maxMemory();
                long dalvikUsed = runtime.totalMemory() - runtime.freeMemory();
                if (dalvikUsed > ((3*dalvikMax)/4)) {
                    if (DEBUG_MEMORY_TRIM) Slog.d(TAG, "Dalvik max=" + (dalvikMax/1024)
                            + " total=" + (runtime.totalMemory()/1024)
                            + " used=" + (dalvikUsed/1024));
                    mSomeActivitiesChanged = false;
                    try {
                        ActivityTaskManager.getService().releaseSomeActivities(mAppThread);
                    } catch (RemoteException e) {
                        throw e.rethrowFromSystemServer();
                    }
                }
            }
        });
    } else {
        // Don't set application object here -- if the system crashes,
        // we can't display an alert, we just want to die die die.
        android.ddm.DdmHandleAppName.setAppName("system_process",
                UserHandle.myUserId());
        try {
            mInstrumentation = new Instrumentation();
            mInstrumentation.basicInit(this);
            ContextImpl context = ContextImpl.createAppContext(
                    this, getSystemContext().mPackageInfo);
            mInitialApplication = context.mPackageInfo.makeApplicationInner(true, null);
            mInitialApplication.onCreate();
        } catch (Exception e) {
            throw new RuntimeException(
                    "Unable to instantiate Application():" + e.toString(), e);
        }
    }

    
    // 设置Configuration变化监听
    ViewRootImpl.ConfigChangedCallback configChangedCallback = (Configuration globalConfig) -> {
        synchronized (mResourcesManager) {
            // We need to apply this change to the resources immediately, because upon returning
            // the view hierarchy will be informed about it.
            if (mResourcesManager.applyConfigurationToResources(globalConfig,
                    null /* compat */)) {
                
                // mInitialApplication是Application对象,在AMS收到ApplicationThread对象之后通知其处理BIND_APPLICATION消息后赋值的
                mConfigurationController.updateLocaleListFromAppContext(
                        mInitialApplication.getApplicationContext());

                // This actually changed the resources! Tell everyone about it.
                final Configuration updatedConfig =
                        mConfigurationController.updatePendingConfiguration(globalConfig);
                if (updatedConfig != null) {
                    // 如果发生配置变化,发送CONFIGURATION_CHANGED消息,然后等待轮询处理
                    sendMessage(H.CONFIGURATION_CHANGED, globalConfig);
                    mPendingConfiguration = updatedConfig;
                }
            }
        }
    };
    ViewRootImpl.addConfigCallback(configChangedCallback);
}

1.2.3 ActivityManagerService#attachApplicationLocked()

OK,在添加Configuration变化回调的时候用到了成员变量mInitialApplication,这个变量不能为空,所以必然是在AMS.attachApplication()过程中被赋值的,所以这样反推,必须去看下这个方法的实现!

@Override
public final void attachApplication(IApplicationThread thread, long startSeq) {
    if (thread == null) {
        throw new SecurityException("Invalid application interface");
    }
    synchronized (this) {
        // 获取process-id,user-id,origId在ATMS中有用到
        int callingPid = Binder.getCallingPid();
        final int callingUid = Binder.getCallingUid();
        final long origId = Binder.clearCallingIdentity();
        // 继续调用实现方法attachApplicationLocked()
        attachApplicationLocked(thread, callingPid, callingUid, startSeq);
        Binder.restoreCallingIdentity(origId);
    }
}

话不多说,继续跟进AMS#attachApplicationLocked()方法

@GuardedBy("this")
private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
                                        int pid, int callingUid, long startSeq) {
                                        
		     // .....
    
    		// 调用IApplicationThread.aidl实现类ApplicationThread的bindApplication()方法
    		thread.bindApplication(processName, appInfo,
                        app.sdkSandboxClientAppVolumeUuid, app.sdkSandboxClientAppPackage,
                        providerList, null, profilerInfo, null, null, null, testMode,
                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
                        isRestrictedBackupMode || !normalMode, app.isPersistent(),
                        new Configuration(app.getWindowProcessController().getConfiguration()),
                        app.getCompat(), getCommonServicesLocked(app.isolated),
                        mCoreSettingsObserver.getCoreSettingsLocked(),
                        buildSerial, autofillOptions, contentCaptureOptions,
                        app.getDisabledCompatChanges(), serializedSystemFontMap,
                        app.getStartElapsedTime(), app.getStartUptime());
}

这里看到,在配置获取了超多参数的值之后,远程调用传进来的ApplicationThread对象的bindApplication()方法,似乎很快就能看到Application对象(mInitialApplication)的赋值地方了!

1.2.4 ApplicationThread#bindApplication()

文件链接:ApplicationThread.aidl

ApplicationThreadIApplicationThread.aidl实现,这个文件中包含了有关四大组件绑定启动,销毁等各种回调方法,

具体的代码看上面的链接。

@Override
public final void bindApplication(String processName, ApplicationInfo appInfo,
                                  String sdkSandboxClientAppVolumeUuid, String sdkSandboxClientAppPackage,
                                  ProviderInfoList providerList, ComponentName instrumentationName,
                                  ProfilerInfo profilerInfo, Bundle instrumentationArgs,
                                  IInstrumentationWatcher instrumentationWatcher,
                                  IUiAutomationConnection instrumentationUiConnection, int debugMode,
                                  boolean enableBinderTracking, boolean trackAllocation,
                                  boolean isRestrictedBackupMode, boolean persistent, Configuration config,
                                  CompatibilityInfo compatInfo, Map services, Bundle coreSettings,
                                  String buildSerial, AutofillOptions autofillOptions,
                                  ContentCaptureOptions contentCaptureOptions, long[] disabledCompatChanges,
                                  SharedMemory serializedSystemFontMap,
                                  long startRequestedElapsedTime, long startRequestedUptime) {
    if (services != null) {
        if (false) {
            // Test code to make sure the app could see the passed-in services.
            for (Object oname : services.keySet()) {
                if (services.get(oname) == null) {
                    continue; // AM just passed in a null service.
                }
                String name = (String) oname;

                // See b/79378449 about the following exemption.
                switch (name) {
                    case "package":
                    case Context.WINDOW_SERVICE:
                        continue;
                }

                if (ServiceManager.getService(name) == null) {
                    Log.wtf(TAG, "Service " + name + " should be accessible by this app");
                }
            }
        }

        // Setup the service cache in the ServiceManager
        ServiceManager.initServiceCache(services);
    }

    setCoreSettings(coreSettings);

    // 新建AppBindData, 用于创建Application
    AppBindData data = new AppBindData();
    data.processName = processName;
    data.appInfo = appInfo;
    data.sdkSandboxClientAppVolumeUuid = sdkSandboxClientAppVolumeUuid;
    data.sdkSandboxClientAppPackage = sdkSandboxClientAppPackage;
    data.providers = providerList.getList();
    data.instrumentationName = instrumentationName;
    data.instrumentationArgs = instrumentationArgs;
    data.instrumentationWatcher = instrumentationWatcher;
    data.instrumentationUiAutomationConnection = instrumentationUiConnection;
    data.debugMode = debugMode;
    data.enableBinderTracking = enableBinderTracking;
    data.trackAllocation = trackAllocation;
    data.restrictedBackupMode = isRestrictedBackupMode;
    data.persistent = persistent;
    data.config = config;
    data.compatInfo = compatInfo;
    data.initProfilerInfo = profilerInfo;
    data.buildSerial = buildSerial;
    data.autofillOptions = autofillOptions;
    data.contentCaptureOptions = contentCaptureOptions;
    data.disabledCompatChanges = disabledCompatChanges;
    data.mSerializedSystemFontMap = serializedSystemFontMap;
    data.startRequestedElapsedTime = startRequestedElapsedTime;
    data.startRequestedUptime = startRequestedUptime;
    
    // 配置好data后,发送BIND_APPLICATION消息,注意此时主线程Loopper并没有对MessageQueue进行轮询哦
    sendMessage(H.BIND_APPLICATION, data);
}

这个方法执行到最后是向MQ中发送一条BIND_APPLICATION消息,大家别忘记了哟,在启动Activity那里,创建进程走完main()方法之后,向ApplicationThread发送了LauncherActivityItem事务和ResumeActivityItem生命周期请求,其中这俩个item最后是调用ApplicationThread#sheduleTransaction()方法处理的。

所以,捋一下,走完ActivityThread#attach()之后,消息队列中有一条BIND_APPLICATION消息,然后对消息队列进行轮询处理之前存入的消息,所以轮询后先处理了BIND_APPLICATION消息,然后再ActivityTaskASupervisor#realStartActivityLocked()那里调用ApplicationThread#sheduleTransaction()处理那俩个ClientTransactionItem,话不多说,先看一下``loop()后处理的第一条消息BIND_APPLICATION,然后看ApplicationThread#sheduleTransaction()吧!消息都是在ActivityThread.H`里处理的

1.2.5 H.handleMessage()H.BIND_APPLICATION

H类中定义了非常多的消息类型,大概有70多种,分别处理了四大组件相关的消息等,很复杂,不过都能一一找到,最后都是汇总到这里根据具体的消息处理具体的操作。

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");
            		// 在AMS.attachApplicationLocked()中创建的AppBindData
                    AppBindData data = (AppBindData)msg.obj;
            		// 调用ActivityThread.handleBindApplition(),完成Application创建
                    handleBindApplication(data);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;
    }
}

最终还是调用ActivityThread#handleBindApplication()

还有其他类似handleXXXX方法,调用链应该差不多。

跟进进去吧!

@UnsupportedAppUsage
private void handleBindApplication(AppBindData data) {
	// VM相关配置
    // 设置时区,时间格式
    // 是否是Debugger模式,是否显示那个"Wait for Debugger"对话框
    // 硬件渲染设置
    
    // Instrumentation info affects the class loader, so load it before
        // setting up the app context.
    
    	// Instrumentation类对象,这个类里面是具体的四大组件相关的操作的逻辑实现类,具体的逻辑代码由这个类承担
        final InstrumentationInfo ii;
        if (data.instrumentationName != null) {
            ii = prepareInstrumentation(data);
        } else {
            ii = null;
        }
    
    	// 创建 ContextImpl
    	final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
    	// 更新ConfigurationController里的context
        mConfigurationController.updateLocaleListFromAppContext(appContext);
    
    	// HTTP相关代理类配置
    // For backward compatibility, TrafficStats needs static access to the application context.
        // But for isolated apps which cannot access network related services, service discovery
        // is restricted. Hence, calling this would result in NPE.
        if (!Process.isIsolated()) {
            TrafficStats.init(appContext);
        }

        // Continue loading instrumentation.
    
    	// 初始化 Instrumentation
        if (ii != null) {
            initInstrumentation(ii, data, appContext);
        } else {
            mInstrumentation = new Instrumentation();
            mInstrumentation.basicInit(this);
        }
    
    
    	// 芜湖!终于看到Application咯
    	Application app;
        final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();
        final StrictMode.ThreadPolicy writesAllowedPolicy = StrictMode.getThreadPolicy();
        try {
            // If the app is being launched for full backup or restore, bring it up in
            // a restricted environment with the base application class.
            
            // 创建App, data.info是LoadedApk对象
            app = data.info.makeApplicationInner(data.restrictedBackupMode, null);

            // Propagate autofill compat state
            app.setAutofillOptions(data.autofillOptions);

            // Propagate Content Capture options
            app.setContentCaptureOptions(data.contentCaptureOptions);
            
            // 向H发送H.SET_CONTENT_CAPTURE_OPTIONS_CALLBACK
            sendMessage(H.SET_CONTENT_CAPTURE_OPTIONS_CALLBACK, data.appInfo.packageName);

            // 看到没,这个mInitialApplication被赋值了,然后再ActivityThread.attach()方法最后面用到了
            mInitialApplication = app;
            
            
            final boolean updateHttpProxy;
            synchronized (this) {
                updateHttpProxy = mUpdateHttpProxyOnBind;
            
            }
            if (updateHttpProxy) {
                ActivityThread.updateHttpProxy(app);
            }

            
            if (!data.restrictedBackupMode) {
                
                // 安装ContentProvider
                if (!ArrayUtils.isEmpty(data.providers)) {
                    installContentProviders(app, data.providers);
                }
            }

            // Do this after providers, since instrumentation tests generally start their
            // test thread at this point, and we don't want that racing.
            try {
                mInstrumentation.onCreate(data.instrumentationArgs);
            }
            catch (Exception e) {
                throw new RuntimeException(
                        "Exception thrown in onCreate() of "
                                + data.instrumentationName + ": " + e.toString(), e);
            }
            
            
            try {
                // OK,终于看到了,调用Application.onCreate()
                mInstrumentation.callApplicationOnCreate(app);
            } catch (Exception e) {
                if (!mInstrumentation.onException(app, e)) {
                    throw new RuntimeException(
                            "Unable to create application " + app.getClass().getName()
                                    + ": " + e.toString(), e);
                }
            }
        } finally {
            // If the app targets < O-MR1, or doesn't change the thread policy
            // during startup, clobber the policy to maintain behavior of b/36951662
            if (data.appInfo.targetSdkVersion < Build.VERSION_CODES.O_MR1
                    || StrictMode.getThreadPolicy().equals(writesAllowedPolicy)) {
                StrictMode.setThreadPolicy(savedPolicy);
            }
        }
    
    	
    	// 加载字体什么的
    	
}

看完代码后心情舒畅,在这段中,看到了Application是由谁创建的,它的onCreate()是谁调用的,以及ContentProvider为什么是在Application之前创建的,接下来按这个逻辑分三部分展开:

1.2.5.1 LoadedApk#makeApplicationInner()

文件指定方法位置:LoadedApk#makeApplicationInner()

具体的代码可以看链接,这里放出创建逻辑

// 缓存中没有app的话就创建一个新的,调用Instrumentation.newApplication()
app = mActivityThread.mInstrumentation.newApplication(
                    cl, appClass, appContext);
  • Instrumentation#newApplication()
    public Application newApplication(ClassLoader cl, String className, Context context)
            throws InstantiationException, IllegalAccessException, 
            ClassNotFoundException {
        // 调用ClassLoader创建app
        Application app = getFactory(context.getPackageName())
                .instantiateApplication(cl, className);
        // 完事之后调用Application.attach(),平平无奇
        app.attach(context);
        return app;
    }
    
    public @NonNull Application instantiateApplication(@NonNull ClassLoader cl,
                @NonNull String className)
                throws InstantiationException, IllegalAccessException, ClassNotFoundException {
            return (Application) cl.loadClass(className).newInstance();
    }
    
    @UnsupportedAppUsage
        /* package */ final void attach(Context context) {
            attachBaseContext(context);
            mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
        }
    
1.2.5.2 ActivityThread#installContentProviders():安装ContentProvider如果需要的话
@UnsupportedAppUsage
private void installContentProviders(Context context, List<ProviderInfo> providers) {
    // 最终走到ContentProvider.onCreate()
}
1.2.5.3 Instrumentation.callApplicationOnCreate():调用Application.onCreate()

先来感受一下callXXOnXXX()系列方法,会有一个整体上的感知。

在这里插入图片描述

public void callApplicationOnCreate(Application app) {
    // 调用Application.onCreate()
    app.onCreate();
}

好的,到这里,已经处理完H.BIND_APPLICATION消息,其中还发送了一个消息H.SET_CONTENT_CAPTURE_OPTIONS_CALLBACK,暂时不管了,就当它也处理了。好的现在是ActivityThread#main()方法走完了,之后还有俩个要处理的消息喔,别忘记了哟:

  1. LauncherActivityItem
  2. ResumeActivityItem

这俩个类均是继承自ClientTransactionItem

好的,后续是远程调用ApplicationThread.sheduleTransaction()处理事务了。

二、H事务处理

1.1 ApplicationThread#sheduleTransaction()

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

调用ActivityThread#scheduleTransaction()方法,注意哦,这个方法并不在ActivityThread类中,而是在它的父类 ClientTransactionHandler中,继续跟进!

public final class ActivityThread extends ClientTransactionHandler
        implements ActivityThreadInternal {
    // ....
}

1.2 ClientTransactionHandler#sheduleTransaction():定义了Activity相关操作的类

文件链接:ClientTransactionHandler

/** Prepare and schedule transaction for execution. */
void scheduleTransaction(ClientTransaction transaction) {
    // 预处理,设置client端相关变量-即ActivityThread对象中一些变量
    transaction.preExecute(this);
    // 发送一条H.EXECUTE_TRANSACTION消息让H处理,obj为当前的事务
    sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}

1.3 H.handleMessage()H.EXECUTE_TRANSACTION

public void handleMessage(Message msg) {
	case EXECUTE_TRANSACTION:
                    final ClientTransaction transaction = (ClientTransaction) msg.obj;
    				// 调用ActivityThread成员变量mTransactionExecutor处理transaction
                    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类中的#execute()方法中;

这个类文件链接:TransactionExecutor

1.3.1 TransactionExecutor.execute(ClientTransaction transaction)
public void execute(ClientTransaction transaction) {
        // ....

    	// 1.执行ClientTransactionItem callbacks
        executeCallbacks(transaction);
		
    	// 2.执行ActivityLifecycleItems requests
        executeLifecycleState(transaction);
        mPendingActions.clear();
       
    }

这里执行executeLifecycleState()时会修正生命周期,先调用onStart()!!!具体请看 链接: Activity的onStart()调用时机

代码不多,可以看到清晰地看到分别处理ClientTransactionItemActivityLifecycleItem,怕你们忘记了,砸门在这里贴一段生成这个俩个东东的地方哈,如下。小过一遍后,继续往下看是怎么处理这俩个东西的吧。

ActivityTaskSupervisor#realStartActivityLocked()


boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
                                boolean andResume, boolean checkConfig) throws RemoteException {
    
    
   				// ....
                final ClientTransaction clientTransaction = ClientTransaction.obtain(
                        proc.getThread(), r.token);

                final boolean isTransitionForward = r.isTransitionForward();
                final IBinder fragmentToken = r.getTaskFragment().getFragmentToken();

                // 1.创建启动activity事务到待处理列表中[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.getFilteredReferrer(r.launchedFromPackage), task.voiceInteractor,
                        proc.getReportedProcState(), r.getSavedState(), r.getPersistentSavedState(),
                        results, newIntents, r.takeOptions(), isTransitionForward,
                        proc.createProfilerInfoIfNeeded(), r.assistToken, activityClientController,
                        r.shareableActivityToken, r.getLaunchedFromBubble(), fragmentToken));

              
                // 2。创建ActivityLifecycleItem对象
                final ActivityLifecycleItem lifecycleItem;
                if (andResume) {
                    // 设置resume-item
                    lifecycleItem = ResumeActivityItem.obtain(isTransitionForward);
                } else {
                    // 设置pause-item
                    lifecycleItem = PauseActivityItem.obtain();
                }
    
    			// 设置lifecycle请求,也就是onCreate之后是onResume
                clientTransaction.setLifecycleStateRequest(lifecycleItem);

                // Schedule transaction.
                // 开始处理事务!~!!!!!!
    			// mService是ActivityTaskManagerService,获取到的lm是ClientLifecycleManager对象
                mService.getLifecycleManager().scheduleTransaction(clientTransaction);
    	
    
    			// ....
}


1.3.1.1 TransactionExecutor.executeCallbacks():分发给具体的ClitentTransactionItem处理
/** Cycle through all states requested by callbacks and execute them at proper times. */
    @VisibleForTesting
    public void executeCallbacks(ClientTransaction transaction) {
        // 拿到所有的TransactionItem
        final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
        // 空判断
        if (callbacks == null || callbacks.isEmpty()) {
            // No callbacks to execute, return early.
            return;
        }

        final IBinder token = transaction.getActivityToken();
        ActivityClientRecord r = mTransactionHandler.getActivityClient(token);

        // In case when post-execution state of the last callback matches the final state requested
        // for the activity in this transaction, we won't do the last transition here and do it when
        // moving to final state instead (because it may contain additional parameters from server).
        
        // 拿到所有的ActivityLifecycleItem,这里是为了获取生命周期顺序状态状态
        final ActivityLifecycleItem finalStateRequest = transaction.getLifecycleStateRequest();
        final int finalState = finalStateRequest != null ? finalStateRequest.getTargetState()
                : UNDEFINED;
        // Index of the last callback that requests some post-execution state.
        final int lastCallbackRequestingState = lastCallbackRequestingState(transaction);

        final int size = callbacks.size();
        // 分发处理各个ClientTransactionItem-----LaunchActivityItem
        for (int i = 0; i < size; ++i) {
            final ClientTransactionItem item = callbacks.get(i);
            final int postExecutionState = item.getPostExecutionState();
            final int closestPreExecutionState = mHelper.getClosestPreExecutionState(r,
                    item.getPostExecutionState());
            if (closestPreExecutionState != UNDEFINED) {
                cycleToPath(r, closestPreExecutionState, transaction);
            }

            // 这里具体执行了LaunchActivityItem.execute()方法
            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);
            }

            if (postExecutionState != UNDEFINED && r != null) {
                // Skip the very last transition and perform it by explicit state request instead.
                final boolean shouldExcludeLastTransition =
                        i == lastCallbackRequestingState && finalState == postExecutionState;
                cycleToPath(r, postExecutionState, shouldExcludeLastTransition, transaction);
            }
        }
    }

逻辑还是很清晰的,因为这是专门处理ClientTransactionItem的,所以获取了所有的,然后遍历分发给具体的实现对象处理,也就是分别调用ClientTransactionItem.execute()方法,由于我们添加进去的是一个LaunchActiivtyItem,所以执行LauncherActivityItem.execute()方法!OKK,GO!

@Override
 public void execute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
     	// 创建ACR
        ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
                mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
                mPendingResults, mPendingNewIntents, mActivityOptions, mIsForward, mProfilerInfo,
                client, mAssistToken, mShareableActivityToken, mLaunchedFromBubble,
                mTaskFragmentToken);
     	// 当前client端是ActivityThread对象(上面说过,它是ClientTransactionHandler子类)
        client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
 }

兜兜转转,最终还是到了ActivityThread

处理LaunchActivityItem最终是转为了一个ActivityClientRecord对象,继而交给具体的ActivityThread.handleLauncherActivity()处理!

当然,ActivityThread还有很多handleXXXX系列方法(方法之多,一屏装不下),原理差不多。

在这里插入图片描述

找到handleLauncherActivity()

1.ActivityThread.handleLauncherActivity()
@Override
    public Activity handleLaunchActivity(ActivityClientRecord r,
            PendingTransactionActions pendingActions, Intent customIntent) {
		// .....
        
        // 初始化WindowManagerGlobal,与WM,WMS强相关
        WindowManagerGlobal.initialize();

        // Hint the GraphicsEnvironment that an activity is launching on the process.
        GraphicsEnvironment.hintActivityLaunch();

        // 哇哦!创建了Activity对象!调用自身的performLaunchActivity()
        final Activity a = performLaunchActivity(r, customIntent);

        // ..

        return a;
    }

看到WindowManagerGlobal被初始化(后续研究WMS,WM,VIEW再细说),还看到Activity被创建,与上面一样,同系列performXXX方法也有很多。

在这里插入图片描述

找到performLaunchActivity()返回俺们的Activity

2.ActivityThread.performLaunchActivity():终于看到Activity.onCreate()
/**  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);
        }

        // 获取appContext
        ContextImpl appContext = createBaseContextForActivity(r);
        // 声明Activity空对象
        Activity activity = null;
        try {
            java.lang.ClassLoader cl = appContext.getClassLoader();
            
            // 调用Instrumentation去new一个Activity,和new Application是一样的
            // 都是通过ClassLoader搞出来的
			// TIPS:由于我们默认创建的Activity是继承自AppComatActivity的(空构造),所以在创建实例的时候会调用其空构造器中的代码,主要是用来初始化AppCompatDelege类,通过ContextAware(实现类为ComponetActivity).addOnContextAvailableListener(),这个回调会在Activity.onCreate()中被调用
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
            
            
            StrictMode.incrementExpectedActivityCount(activity.getClass());
            r.intent.setExtrasClassLoader(cl);
            r.intent.prepareToEnterProcess(isProtectedComponent(r.activityInfo),
                    appContext.getAttributionSource());
            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 app = r.packageInfo.makeApplication(false, mInstrumentation);

            if (activity != null) {
                CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
                Configuration config =
                        new Configuration(mConfigurationController.getCompatConfiguration());
                if (r.overrideConfig != null) {
                    config.updateFrom(r.overrideConfig);
                }
               
                // 配置window,复用之前的
                Window window = null;
                if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
                    window = r.mPendingRemoveWindow;
                    r.mPendingRemoveWindow = null;
                    r.mPendingRemoveWindowManager = null;
                }

                // Activity resources must be initialized with the same loaders as the
                // application context.
                appContext.getResources().addLoaders(
                        app.getResources().getLoaders().toArray(new ResourcesLoader[0]));

                appContext.setOuterContext(activity);
                
                // !!!! activity对象创建好之后,调用其attach()方法,完成内部变量初始化
                // PhoneWindow,title.....
                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, r.shareableActivityToken);

                if (customIntent != null) {
                    activity.mIntent = customIntent;
                }
                r.lastNonConfigurationInstances = null;
                checkAndBlockForNetworkAccess();
                activity.mStartedActivity = false;
                int theme = r.activityInfo.getThemeResource();
                
                // 如果设置了自定义的主题,设置上去
                if (theme != 0) {
                    activity.setTheme(theme);
                }

                if (r.mActivityOptions != null) {
                    activity.mPendingOptions = r.mActivityOptions;
                    r.mActivityOptions = null;
                }
                activity.mLaunchedFromBubble = r.mLaunchedFromBubble;
                activity.mCalled = false;
                
                // 根据是否是持久化的来调用Acitivty.onCreate(),主要是参数个数不同,有些同学会写成三个参数的onCreate()从而导致为啥我的onCreate()不执行的问题
                if (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    // 与上面Application.onCreate()调用是一样的
                    // 调用了核心逻辑实现类Instrumentation.callActivityOnCreate()
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
                
                // 检查Activity子类是否调用对应的super.method,也就是为什么我们重写onCreate(),如果吧super.onCreate()去掉AS会提示缺少CallSuper异常
                if (!activity.mCalled) {
                    throw new SuperNotCalledException(
                        "Activity " + r.intent.getComponent().toShortString() +
                        " did not call through to super.onCreate()");
                }
                r.activity = activity;
                mLastReportedWindowingMode.put(activity.getActivityToken(),
                        config.windowConfiguration.getWindowingMode());
            }
            
            // 设置Activity声明周期为onCreate
            r.setState(ON_CREATE);

            // updatePendingActivityConfiguration() reads from mActivities to update
            // ActivityClientRecord which runs in a different thread. Protect modifications to
            // mActivities to avoid race.
            synchronized (mResourcesManager) {
                mActivities.put(r.token, r);
            }

        } catch (SuperNotCalledException e) {
            throw e;

        } catch (Exception e) {
            if (!mInstrumentation.onException(activity, e)) {
                throw new RuntimeException(
                    "Unable to start activity " + component
                    + ": " + e.toString(), e);
            }
        }

        return activity;
    }

OKK,在这个方法中我们看到Activity对象的创建也是由Instrumetation负责,先是调用Activity.attach(),然后调用了Activity.onCreate()方法!

我们看完了LaunchActivityItem的处理,再来看ResumeActivityItem的处理,不知道你们忘记了没有,其对应的方法是:

public void execute(ClientTransaction transaction) {
        // ....

    	// 1.执行ClientTransactionItem callbacks
        executeCallbacks(transaction);
		
    	// 2.执行ActivityLifecycleItems requests
        executeLifecycleState(transaction);
        mPendingActions.clear();
       
    }

让我们回到这一小节的TransactionExecutor.execute()方法中,在1.3.1.1中完成了executeCallbacks(transaction)方法执行,然后就是轮到ResumeActivityItem(extend ActivityLifecycleItem)的处理!

1.3.1.2 TransactionExecutor.executrLifecycleState():分发给具体的ActivityLifecycleItem处理
/** Transition to the final state if requested by the transaction. */
    private void executeLifecycleState(ClientTransaction transaction) {
        final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
        // onResume之后,activity正常走,不做什么隐藏,主题变化等,就不会有生命周期改变
        if (lifecycleItem == null) {
            // No lifecycle request, return early.
            return;
        }

        final IBinder token = transaction.getActivityToken();
        final ActivityClientRecord r = mTransactionHandler.getActivityClient(token);

        if (r == null) {
            // Ignore requests for non-existent client records for now.
            return;
        }

        // 确保生命周期顺序正确
        // Cycle to the state right before the final requested state.
        cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */, transaction);

        // Execute the final transition with proper parameters.
        // 同处理ClientTransactionItem一样,调用其execute()方法
        lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
        
        lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
    }

这里看到和上面的差不多,分发给ReusmeActivityItem自己处理,同理其他的生命周期item也是一样的。

还是调用ActivityThread.handleXXX系列方法。

此处调用handleResumeActivity()

 @Override
    public void execute(ClientTransactionHandler client, ActivityClientRecord r,
            PendingTransactionActions pendingActions) {
        //Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
        client.handleResumeActivity(r, true /* finalStateRequest */, mIsForward,
                "RESUME_ACTIVITY");
        //Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }
1. ActivityThread.handleResumeActivity()
@Override
    public void handleResumeActivity(ActivityClientRecord r, boolean finalStateRequest,
            boolean isForward, String reason) {
		// ....

        // TODO Push resumeArgs into the activity for consideration
        // skip below steps for double-resume and r.mFinish = true case.
        
        // 执行performResumeActivity()
        if (!performResumeActivity(r, finalStateRequest, reason)) {
            return;
        }
        if (mActivitiesToBeDestroyed.containsKey(r.token)) {
            // Although the activity is resumed, it is going to be destroyed. So the following
            // UI operations are unnecessary and also prevents exception because its token may
            // be gone that window manager cannot recognize it. All necessary cleanup actions
            // performed below will be done while handling destruction.
            return;
        }

        final Activity a = r.activity;

        final int forwardBit = isForward
                ? WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0;

        // If the window hasn't yet been added to the window manager,
        // and this guy didn't finish itself or start another activity,
        // then go ahead and add the window.
        boolean willBeVisible = !a.mStartedActivity;
        if (!willBeVisible) {
            willBeVisible = ActivityClient.getInstance().willActivityBeVisible(
                    a.getActivityToken());
        }

		// =================== 准备关联WM WMS ViewRootImpl DecorView,
        if (r.window == null && !a.mFinished && willBeVisible) {
            r.window = r.activity.getWindow();
            View decor = r.window.getDecorView();
            decor.setVisibility(View.INVISIBLE);
            ViewManager wm = a.getWindowManager();
            WindowManager.LayoutParams l = r.window.getAttributes();
            a.mDecor = decor;
			// 设置该window为应用程序顶级窗口
            l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
            l.softInputMode |= forwardBit;
            if (r.mPreserveWindow) {
                a.mWindowAdded = true;
                r.mPreserveWindow = false;
                // Normally the ViewRoot sets up callbacks with the Activity
                // in addView->ViewRootImpl#setView. If we are instead reusing
                // the decor view we have to notify the view root that the
                // callbacks may have changed.
                ViewRootImpl impl = decor.getViewRootImpl();
                if (impl != null) {
                    impl.notifyChildRebuilt();
                }
            }
            if (a.mVisibleFromClient) {
                if (!a.mWindowAdded) {
                    a.mWindowAdded = true;
                    // 将DecorView和ViewRootImpl等关联起来,准备三大流程
                    wm.addView(decor, l);
                } else {
                    // The activity will get a callback for this {@link LayoutParams} change
                    // earlier. However, at that time the decor will not be set (this is set
                    // in this method), so no action will be taken. This call ensures the
                    // callback occurs with the decor set.
                    a.onWindowAttributesChanged(l);
                }
            }

            // If the window has already been added, but during resume
            // we started another activity, then don't yet make the
            // window visible.
        } else if (!willBeVisible) {
            if (localLOGV) Slog.v(TAG, "Launch " + r + " mStartedActivity set");
            r.hideForNow = true;
        }

        // Get rid of anything left hanging around.
        cleanUpPendingRemoveWindows(r, false /* force */);

        // The window is now visible if it has been added, we are not
        // simply finishing, and we are not starting another activity.
        if (!r.activity.mFinished && willBeVisible && r.activity.mDecor != null && !r.hideForNow) {
            if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward=" + isForward);
            ViewRootImpl impl = r.window.getDecorView().getViewRootImpl();
            WindowManager.LayoutParams l = impl != null
                    ? impl.mWindowAttributes : r.window.getAttributes();
            if ((l.softInputMode
                    & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)
                    != forwardBit) {
                l.softInputMode = (l.softInputMode
                        & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION))
                        | forwardBit;
                if (r.activity.mVisibleFromClient) {
                    ViewManager wm = a.getWindowManager();
                    View decor = r.window.getDecorView();
                    
                 
                    wm.updateViewLayout(decor, l);
                }
            }

            r.activity.mVisibleFromServer = true;
            mNumVisibleActivities++;
            if (r.activity.mVisibleFromClient) {
                r.activity.makeVisible();
            }
        }

        r.nextIdle = mNewActivities;
        mNewActivities = r;
        if (localLOGV) Slog.v(TAG, "Scheduling idle handler for " + r);
        Looper.myQueue().addIdleHandler(new Idler());
    }

可以看到还是得执行performResumeActivity(),和之前oncreate时一样,之后就是和Window-DecorView-RootView-三大流程相关了。

2.ActivityThread.performResumeActivity()
    public boolean performResumeActivity(ActivityClientRecord r, boolean finalStateRequest,
            String reason) {
        
        if (r.activity.mFinished) {
            return false;
        }
        
        // 在performLaunchActivity()那里,r.setState(ON_CREATE),如果走到这里,state居然为onResume,那么就是意外情况了
        if (r.getLifecycleState() == ON_RESUME) {
            if (!finalStateRequest) {
                final RuntimeException e = new IllegalStateException(
                        "Trying to resume activity which is already resumed");
                Slog.e(TAG, e.getMessage(), e);
                Slog.e(TAG, r.getStateString());
                // TODO(lifecycler): A double resume request is possible when an activity
                // receives two consequent transactions with relaunch requests and "resumed"
                // final state requests and the second relaunch is omitted. We still try to
                // handle two resume requests for the final state. For cases other than this
                // one, we don't expect it to happen.
            }
            return false;
        }
        if (finalStateRequest) {
            r.hideForNow = false;
            r.activity.mStartedActivity = false;
        }
        try {
            r.activity.onStateNotSaved();
            r.activity.mFragments.noteStateNotSaved();
            checkAndBlockForNetworkAccess();
            if (r.pendingIntents != null) {
                deliverNewIntents(r, r.pendingIntents);
                r.pendingIntents = null;
            }
            if (r.pendingResults != null) {
                deliverResults(r, r.pendingResults, reason);
                r.pendingResults = null;
            }
            
           	// !!!  调用Activity.performResume()
            r.activity.performResume(r.startsNotResumed, reason);

            r.state = null;
            r.persistentState = null;
            
            // 生命周期右 ON_CREATE -> ON_RESUME
            r.setState(ON_RESUME);

            reportTopResumedActivityChanged(r, r.isTopResumedActivity, "topWhenResuming");
        } catch (Exception e) {
            if (!mInstrumentation.onException(r.activity, e)) {
                throw new RuntimeException("Unable to resume activity "
                        + r.intent.getComponent().toShortString() + ": " + e.toString(), e);
            }
        }
        return true;
    }

可以看到,先做了不正常生命周期判断,正常流程就是执行Activity.performResume(),然后更新ActivityClientRecor中的生命周期,由ON_CREATE---->ON_RESUME

3. Activity.performResume()

Activity中也有系列方法:

在这里插入图片描述

final void performResume(boolean followedByPause, String reason) {
    
    	// 调用Application分发ActivityLifecycleCallbacks注册回调
        dispatchActivityPreResumed();
    
    	// 这里看判断是不是STTOPED,如果是执行onRestart,由于是从oncreate->onresume,并没有到onstop,所以这这个方法并不会执行完整
        performRestart(true /* start */, reason);

        mFragments.execPendingActions();

        mLastNonConfigurationInstances = null;

        // ...
		
        mCalled = false;
        // mResumed is set by the instrumentation
    
    	// 同oncreate,还是调用Instrumentation.callActivityOnResume()
        mInstrumentation.callActivityOnResume(this);
    
        
  		// .....
    
    	// fragment相关
        mFragments.dispatchResume();
        mFragments.execPendingActions();

        onPostResume();
    
    // ...检测是否CallSuper
        if (!mCalled) {
            throw new SuperNotCalledException(
                "Activity " + mComponent.toShortString() +
                " did not call through to super.onPostResume()");
        }
        dispatchActivityPostResumed();
        Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
    }

判断是否需要restart,然后调用Instrumentation.callActiivtyOnResume()

public void callActivityOnResume(Activity activity) {
        activity.mResumed = true;
    
    	// 调用Activity.onResume
        activity.onResume();
        
        if (mActivityMonitors != null) {
            synchronized (mSync) {
                final int N = mActivityMonitors.size();
                for (int i=0; i<N; i++) {
                    final ActivityMonitor am = mActivityMonitors.get(i);
                    am.match(activity, activity, activity.getIntent());
                }
            }
        }
    }

到这,我们看到了Activity.onResume()被调用!

至此,ActivityThread.handleResume()方法中的performResumeActivity()执行完了,然后会继续执行和Window相关显示,开启View三大流程将Activity默认布局显示出来(如果在Activity.onCreate()还设置了setContnentView(layoutResId),还会继续显示),这也解释了为什么onCreate()onResume()获取不到View的宽高!!!!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值