0
点赞
收藏
分享

微信扫一扫

安卓Activity的创建和启动流程源码分析

佛贝鲁先生 2022-03-12 阅读 54

概述

安卓开发的程序猿都知道四大组件之一的Activity的重要性,但可能有很多人并不了解Activity的创建流程和声生命周期调用流程,只是在运用上行云流水。

那么希望这篇文章对那些还不够了解Activity的同志们来说能有所帮助。

注:以下源码基于Android11

Android入口函数

在Java程序里,项目的入口函数是main函数,这个想必大家也都知道,那么我们安卓项目又是怎么启动的呢?对,不要怀疑,在我们开发的安卓项目中,也是有一个入口main函数,安卓中这个main函数在源码ActivityThread.java类中:

//ActivityThread.java
public static void main(String[] args) {
    ...此处省略一万个字母
}

是不是很眼熟,跟Java中一样。当我们点击手机屏幕上的App图标开启应用的时候,Android首先调用的是这个main方法,ApplicationActivity就在这个main函数中创建。

源码分析

接下来我们就进入源码分析环节,直接看mian方法里面的源码:

//ActivityThread.java
public static void main(String[] args) {
    ...
    //为主线程创建Looper
     Looper.prepareMainLooper();
    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()));
            }
        }
    }
    //1.创建ActivityThread
    ActivityThread thread = new ActivityThread();
    //2.将当前app与Android系统的AMS服务连接起来,记住此处attach方法的第一个参数
    thread.attach(false, startSeq);
    ...
    Looper.loop();
    throw new RuntimeException("Main thread loop unexpectedly exited");
}

上面注释1的部分创建了ActivityThread,然后在注释2的部分调用了attach方法,接下来我们点进thread.attach(false, startSeq)方法里面继续看:

//ActivityThread.java
private void attach(boolean system, long startSeq) {
    if (!system) {
        ...
        //1.获取AMS的本地代理对象IActivityManager
        final IActivityManager mgr = ActivityManager.getService();
        try {
            //2.绑定Application
            mgr.attachApplication(mAppThread, startSeq);
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
        ...
    } else {
        ...
    }
}

在上面的attach方法里面,注释1的部分,通过AIDL,获取了AMS的本地代理对象IActivityManager,它是作为应用进程请求系统进程的接口,实现跟AMS服务跨进程通信(通过AIDL实现跨进程通信)。然后上面注释2的部分通过IActivityManager实例调用attachApplication方法,该方法主要是绑定Application,让AMS跟Application连接起来,从而让当前app跟Android系统实现绑定,方便系统管理当前app。接着进入mgr.attachApplication(mAppThread, startSeq)方法里面:

//ActivityManagerService.java
public final void attachApplication(IApplicationThread thread, long startSeq) {
    if (thread == null) {
        throw new SecurityException("Invalid application interface");
    }
    synchronized (this) {
        //1.获取pid(系统创建并分配)
        int callingPid = Binder.getCallingPid();
        //2.获取uid(系统创建并分配)
        final int callingUid = Binder.getCallingUid();
        final long origId = Binder.clearCallingIdentity();
        //3.连接Application
        attachApplicationLocked(thread, callingPid, callingUid, startSeq);
        Binder.restoreCallingIdentity(origId);
    }
}

此处需要说明一下,attachApplicationActivityManagerService中的方法,ActivityManagerService继承了IActivityManagerStub内部类:

ActivityManagerService

当获取到pid和uid之后,紧接着将这两个值作为参数传入到attachApplicationLocked方法里面,来看看这个方法:

//ActivityManagerService.java
@GuardedBy("this")
private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
        int pid, int callingUid, long startSeq) {
    //1.进程记录类
    ProcessRecord app;
    ...
    if (pid != MY_PID && pid >= 0) {
        synchronized (mPidsSelfLocked) {
            //2.通过pid获取进程记录类
            app = mPidsSelfLocked.get(pid);
        }
        ...
    }
    ...
    //通过ProcessRecord实例获取ActiveInstrumentation实例
    final ActiveInstrumentation instr2 = app.getActiveInstrumentation();
    ...
    if (app.isolatedEntryPoint != null) {
        ...
    } else if (instr2 != null) {//当前进程是否处于活动状态
        //3.绑定到当前线程
        thread.bindApplication(processName, appInfo, providerList,
               instr2.mClass,
               profilerInfo, instr2.mArguments,
               instr2.mWatcher,
               instr2.mUiAutomationConnection, testMode,
               mBinderTransactionTrackingEnabled, enableTrackAllocation,
               isRestrictedBackupMode || !normalMode, app.isPersistent(),
               new Configuration(app.getWindowProcessController().getConfiguration()),
                                 app.compat, getCommonServicesLocked(app.isolated),
                                 mCoreSettingsObserver.getCoreSettingsLocked(),
                                 buildSerial, autofillOptions, contentCaptureOptions,
                                 app.mDisabledCompatChanges);
    } else {
        //4.绑定到当前线程
        thread.bindApplication(processName, appInfo, providerList, null, profilerInfo,
               null, null, null, testMode,
               mBinderTransactionTrackingEnabled, enableTrackAllocation,
               isRestrictedBackupMode || !normalMode, app.isPersistent(),
               new Configuration(app.getWindowProcessController().getConfiguration()),
                                 app.compat, getCommonServicesLocked(app.isolated),
                                 mCoreSettingsObserver.getCoreSettingsLocked(),
                                 buildSerial, autofillOptions, contentCaptureOptions,
                                 app.mDisabledCompatChanges);
    }
    ...
    if (normalMode) {
        try {   
            //5.创建activity
            didSomething = mAtmInternal.attachApplication(
                          app.getWindowProcessController());
        } catch (Exception e) {
            Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
            badApp = true;
        }
    }
    ...
}

首先是通过pid获取到进程记录类ProcessRecord的实例对象,该类是用来保存当前进程的一些信息(如:pid、uid、ApplicationInfo等)。然后通过该实例获取到ActiveInstrumentation实例,继而通过ActiveInstrumentation实例来判断当前进程是否在运行,通过跟踪app.getActiveInstrumentation()方法可以知道,在ProcessRecord类中声明ActiveInstrumentation类型变量的地方有一处注释解释这个变量的作用,如图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BTv5lY48-1646929087115)(https://cdn.jsdelivr.net/gh/JessonYang/pic-cloud@main/img/Snipaste_2022-03-03_17-47-33.png)]

然后通过instr2来判断当前进程是否在活动,在上面第3和第4部分的源码,就是绑定application的,而这里的thread.bindApplication方法是IApplicationThread里面的方法,但是在ActivityThread里面有个ApplicationThread内部类,这个内部类继承了IApplicationThread的内部类Stub,所以thread.bindApplication方法最终调用的是ActivityThread的内部类ApplicationThread里面的bindApplication方法,故我们找到这个方法:

//ActivityThread.ApplicationThread.java 
@Override
 public final void bindApplication(String processName, ApplicationInfo appInfo,
         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) {
     ...
     //1.将该方法的参数等信息封装到AppBindData对象中
     AppBindData data = new AppBindData();
     data.processName = processName;
     data.appInfo = appInfo;
     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;
     //2.通过Handler发送消息,并携带AppBindData参数
     sendMessage(H.BIND_APPLICATION, data);
 }

通过上面bindApplication方法的源码可以看出,在该方法里面对入参进行一个封装,然后采用Handler机制携带AppBindData对象发送消息。通过sendMessage方法的第一个参数可以发现,接收消息的what标志是定义在一个H的类里面,由此可以想到,最终处理这条消息的handleMessage方法应该也在这个H类里面,我们进入到这个H类里面,果然,很快就可以发现H类是Handler的子类,并且可以找到handleMessage方法,在这里可以看到对BIND_APPLICATION的处理逻辑:

//ActivityThread.H.java 
public void handleMessage(Message msg) {
     ...
     switch (msg.what) {
         //1.绑定application
         case BIND_APPLICATION:
              Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
              //2.获取传过来的AppBindData实例
              AppBindData data = (AppBindData)msg.obj;
              //3.调用handleBindApplication方法处理逻辑
              handleBindApplication(data);
              Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
              break;
     }
    ...
 }

handleMessage接收到消息后,通过handleBindApplication方法来处理逻辑:

//ActivityThread.java
@UnsupportedAppUsage
private void handleBindApplication(AppBindData data) {
    ...
    //1.创建ApplicationContext
    final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
    ...
    //2.声明Application
    Application app;
    ...
    //3.创建Application
    app = data.info.makeApplication(data.restrictedBackupMode, null);
    ...
    if (!data.restrictedBackupMode) {
        if (!ArrayUtils.isEmpty(data.providers)) {
            //从这里可以看出ContentProvider要先于application.onCreate执行
            installContentProviders(app, data.providers);
        }
    }
    try {
        //调用Application的onCreate方法
        mInstrumentation.callApplicationOnCreate(app);
     } catch (Exception e) {
       ...
    }
}

以上第1处的源码为应用生成了上下文Context,即通过getApplicationContext()获取到的ContextImpl,ContextImplContext的子类,然后通过data.info.makeApplication(data.restrictedBackupMode, null)方法创建app,我们看一下这个方法:

//LoadedApk.java
@UnsupportedAppUsage
public Application makeApplication(boolean forceDefaultAppClass,
        Instrumentation instrumentation) {
    if (mApplication != null) {
        //1.如果不为空,直接返回
        return mApplication;
    }
    ...
    Application app = null;
    //2.获取Application的className
    String appClass = mApplicationInfo.className;
    if (forceDefaultAppClass || (appClass == null)) {
        //3.如果获取到的appClass为空,则使用默认Application的className
        appClass = "android.app.Application";
    }
    try {
        //4.获取类加载器ClassLoader
        final java.lang.ClassLoader cl = getClassLoader();
        if (!mPackageName.equals("android")) {
            ...
            initializeJavaContextClassLoader();
            ...
        }
        ...
        ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
        ...
        //5.通过反射创建Application
        app = mActivityThread.mInstrumentation.newApplication(cl, appClass, appContext);
        appContext.setOuterContext(app);
    } catch (Exception e) {
        ...
    }
    mActivityThread.mAllApplications.add(app);
    mApplication = app;
}

通过上面的makeApplication方法源码,可以很清晰的知道,Application是通过类加载器和反射创建的。上面第2步首先获取ApplicationclassName,此处获取的className即为我们项目中manifests文件中的application节点中name属性定义的Application,然后在下面第3步对这个className进行判空,如果为空的话,就赋值为默认的className。紧接着获取类加载器,然后在第5步通过类加载器和className利用反射创建Application

到此Application就创建完成,然后我们回到前面ActivityThread.java类中的handleBindApplication方法,创建完Application之后,调用了mInstrumentation.callApplicationOnCreate(app)方法,该方法源码如下:

//Instrumentation.java
/**
 * Perform calling of the application's {@link Application#onCreate}
 * method.  The default implementation simply calls through to that method.
 *
 * <p>Note: This method will be called immediately after {@link #onCreate(Bundle)}.
 * Often instrumentation tests start their test thread in onCreate(); you
 * need to be careful of races between these.  (Well between it and
 * everything else, but let's start here.)
 *
 * @param app The application being created.
 */
public void callApplicationOnCreate(Application app) {
    app.onCreate();
}

简洁明了,这个方法里面直接调用了ApplicationonCreate方法,方法上面的注释也说明的很清楚。

Application创建总结

简单总结一下Application的创建流程,大致就是三大步:第一步获取pic和uid,第二部通过IApplicationThread请求当前应用进程,第三步便是通过反射创建Application

Activity的创建

看完了Application,接下来我们把目光回调到上述ActivityManagerService.java类中的attachApplicationLocked方法中的第五步,通过mAtmInternal.attachApplication(app.getWindowProcessController())方法创建Activity,这个方法是抽象类ActivityTaskManagerInternal中的方法,那这个方法的实现类在哪里呢?可能有很多朋友会有这个疑问,会觉得这个实现类不太好找,别慌张,接下来我们一步步的找到这个实现类。
首先看一看ActivityTaskManagerInternal抽象类:

/**
 * Activity Task manager local system service interface.
 * @hide Only for use within system server
 */
public abstract class ActivityTaskManagerInternal {
    ...
}

注意看注释,介绍了这个类是什么什么什么系统服务接口,既然是什么什么什么系统服务的接口,那么这个什么什么什么系统服务肯定会实现它,那我们搜一下这个什么ActivityTaskManager的服务类,可以找到有一个ActivityTaskManagerService类:

public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
    ...
}

然后看看这个类里面有没有ActivityTaskManagerInternal里面的attachApplication方法,一经搜索,发现的确有实现这个方法,但是是ActivityTaskManagerService的一个内部类LocalService实现的,而LocalService继承了抽象类ActivityTaskManagerInternal

//ActivityTaskManagerService.LocalService.java
final class LocalService extends ActivityTaskManagerInternal {
    ...
    @HotPath(caller = HotPath.PROCESS_CHANGE)
    @Override
    public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
        synchronized (mGlobalLockWithoutBoost) {
            ...
            try {
                return mRootWindowContainer.attachApplication(wpc);
            } finally {
                ...
            }
        }
    }
    ...
}

到这里便真相大白了,接下来我们验证一下attachApplication方法到底是不是调用到这里来的,我们知道attachApplication方法的调用者是mAtmInternal,那么我们试着找到这个变量的赋值代码,果然有:

//ActivityManagerService.java
mAtmInternal = LocalServices.getService(ActivityTaskManagerInternal.class);

噢,原来是调用了LocalServices的一个静态方法进行赋值的,点进去瞅一瞅:

//LocalServices.java
/**
 * Returns a local service instance that implements the specified interface.
 *
 * @param type The type of service.
 * @return The service object.
 */ 
@SuppressWarnings("unchecked")
public static <T> T getService(Class<T> type) {
    synchronized (sLocalServiceObjects) {
        return (T) sLocalServiceObjects.get(type);
    }
}

完蛋,这又是个什么鬼,就两行代码,也不知道具体是返回了个什么类型的实例,稳住,淡定的来分析一波,此处只是从sLocalServiceObjects中取出了一个值并return,而这个sLocalServiceObjects可以发现是一个ArrayMap

//LocalServices.java
private static final ArrayMap<Class<?>, Object> sLocalServiceObjects = new ArrayMap<Class<?>, Object>();

既然是从这个ArrayMap中通过key取出来一个值返回的,那么必定在某个隐秘的地方会通过这个key添加一个实例值,而这个key便是我们调用这个方法的时候传递进来的,也就是ActivityTaskManagerInternal.class,顺着这个思路,找找sLocalServiceObjectsput方法,很快就可以找到有个静态方法里面调用了put方法添加元素:

//LocalServices.java
/**
 * Adds a service instance of the specified interface to the global registry of local services.
 */
public static <T> void addService(Class<T> type, T service) {
    synchronized (sLocalServiceObjects) {
        if (sLocalServiceObjects.containsKey(type)) {
            throw new IllegalStateException("Overriding service registration");
        }
        sLocalServiceObjects.put(type, service);
    }
}

然后我们猜想在ActivityTaskManagerService.java类里面或许有调用addService添加元素,经过一番搜索,就会发现确实有:

//ActivityTaskManagerService.java
private void start() {
   LocalServices.addService(ActivityTaskManagerInternal.class, mInternal);
}

start()方法里面通过ActivityTaskManagerInternal.class这个key添加了一个mInternal实例,这里我们不用管这个start()方法在什么时候调用的,反正肯定在LocalServices.getService(ActivityTaskManagerInternal.class)之前调用的,所以直接搜索这个mInternal实例,会发现在ActivityTaskManagerService的构造函数里面初始化了这个变量:

//ActivityTaskManagerService.java
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
public ActivityTaskManagerService(Context context) {
    ...
    mInternal = new LocalService();
    ...
}

至此,便可以验证ActivityManagerService里面通过LocalServices.getService(ActivityTaskManagerInternal.class)获取到的实例便是此处继承了抽象类ActivityTaskManagerInternalLocalService实例。

接下来我们来看LocalService实现的attachApplication方法:

//ActivtyTaskManagerService.LocalService.java
@HotPath(caller = HotPath.PROCESS_CHANGE)
@Override
public boolean attachApplication(WindowProcessController wpc) throws RemoteException {
    synchronized (mGlobalLockWithoutBoost) {
        ...
        try {
            return mRootWindowContainer.attachApplication(wpc);
        } finally {
            ...
        }
    }
}

继续进入mRootWindowContainer.attachApplication(wpc)方法里面:

//RootWindowContainer.java
boolean attachApplication(WindowProcessController app) throws RemoteException {
    ...
    final PooledFunction c = PooledLambda.obtainFunction(
        RootWindowContainer::startActivityForAttachedApplicationIfNeeded, 
        this,
        PooledLambda.__(ActivityRecord.class),
        app, 
        stack.topRunningActivity());
    ...
}

这个方法里面又调用了RootWindowContainer::startActivityForAttachedApplicationIfNeeded,我们继续看:

//RootWindowContainer.java
private boolean startActivityForAttachedApplicationIfNeeded(ActivityRecord r,WindowProcessController app, ActivityRecord 
                                                            top) {
    ...
    try {
        //调用到ActivityStackSupervisor.realStartActivityLocked方法
        if (mStackSupervisor.realStartActivityLocked(r, app, top == r /*andResume*/,true /*checkConfig*/)) {
            mTmpBoolean = true;
        }
    } catch (RemoteException e) {
       ...
    }
    ...
}

一层一层一层又一层,继续看这个realStartActivityLocked方法:

//ActivityStackSupervisor.java
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,boolean andResume, boolean checkConfig) 
    throws RemoteException {
    ...
    // Create activity launch transaction.
    //创建启动activity
    final ClientTransaction clientTransaction = ClientTransaction.obtain(proc.getThread(), r.appToken);
    ...
    //1.添加LaunchActivityItem的回调,后面执行activity生命周期会用到
    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()));
    ...
    // Schedule transaction.
    //2.通过生命周期管理对象管理Activity的生命周期
    mService.getLifecycleManager().scheduleTransaction(clientTransaction);
    ...
}

第2部分的代码便是对activity生命周期的管理,接着看:

//ClientLifecycleManager.java
void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
    final IApplicationThread client = transaction.getClient();
    //调用ClientTransaction中的schedule方法
    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();
    }
}

进入ClientTransaction

//ClientTransaction.java
public void schedule() throws RemoteException {
    //mClient为IApplicationThread的实例
    mClient.scheduleTransaction(this);
}

这里的mClientIApplicationThread对象,而在前面有说到ActivityThread的内部类ApplicationThread继承了IApplicationThread的内部类Stub,所以在ApplicationThread中扩展了这个scheduleTransaction方法:

//ActivityThread.ApplicationThread.java
@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
    //此处走到了ActivityThread的父类ClientTransactionHandler中的scheduleTransaction方法
    ActivityThread.this.scheduleTransaction(transaction);
}

在这里我们看到调用了ActivityThread的对象方法scheduleTransaction,但是ActivityThread里面并没有这个方法,其实这里是调用的它的父类ClientTransactionHandler中的scheduleTransaction方法:

//ClientTransactionHandler.java
void scheduleTransaction(ClientTransaction transaction) {
    transaction.preExecute(this);
    //发送Handler消息到ActivityThread.H
    sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}

然后就是通过Handler发送消息到ActivityThread.H中的handleMessage

//ActivityThread.H.java
public void handleMessage(Message msg) {
    if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
    switch (msg.what) {
        ...
        case EXECUTE_TRANSACTION:
            final ClientTransaction transaction = (ClientTransaction) msg.obj;
            //1.开始执行
            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;
        ...
    }
}

直接看第1处的执行方法:

//TransactionExecutor.java
public void execute(ClientTransaction transaction) {
    ...
    //1.执行回调
    executeCallbacks(transaction);
    //2.执行生命周期状态的改变
    executeLifecycleState(transaction);
}

首先是执行回调,然后紧接着处理生命周期的状态改变,这里我们重点来看executeCallbacks方法:

//TransactionExecutor.java
@VisibleForTesting
public void executeCallbacks(ClientTransaction transaction) {
    //1.获取ClientTransactionItem回调集合,此处获取的ClientTransactionItem是LaunchActivityItem
    final List<ClientTransactionItem> callbacks = transaction.getCallbacks();
    ...
    final int size = callbacks.size();
    for (int i = 0; i < size; ++i) {
        //2.获取集合中的ClientTransactionItem(实际是LaunchActivityItem实例)
        final ClientTransactionItem item = callbacks.get(i);
        ...
        //3.调用LaunchActivityItem的execute方法执行
        item.execute(mTransactionHandler, token, mPendingActions);
        ...
    }
}

第1步中首先便是通过transaction获取回调集合,这里大家可能会疑惑为什么是LaunchActivityItem,因为前面在clientTransaction.addCallback()的时候添加的就是LaunchActivityItem实例,那我们继续看LaunchActivityItem中的execute方法:

//LaunchActivityItem.java
@Override
public void execute(ClientTransactionHandler client, IBinder token, PendingTransactionActions pendingActions) {
    ...
    //调用ClientTransactionHandler的handleLaunchActivity方法
    client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
    ...
}

这里ClientTransactionHandler是抽象类,而ActivityThread继承了这个类,因此我们看ActivityThread里面的handleLaunchActivity的实现:

//ActivityThread.java
@Override
public Activity handleLaunchActivity(ActivityClientRecord r, PendingTransactionActions pendingActions, Intent customIntent) {
    ...
    //创建并启动activity
    final Activity a = performLaunchActivity(r, customIntent);
    ...
}

/**  Core implementation of activity launch. */
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    //获取activity信息
    ActivityInfo aInfo = r.activityInfo;
    ...
    //获取component
    ComponentName component = r.intent.getComponent();
    //获取上下文
    ContextImpl appContext = createBaseContextForActivity(r);
    Activity activity = null;
    try {
        //获取ClassLoader
        java.lang.ClassLoader cl = appContext.getClassLoader();
        //通过ClassLoader加载activity,再通过反射创建activity实例
        activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);
        ...
    } catch (Exception e) {
        ...
    }
    try {
        //获取Application
        Application app = r.packageInfo.makeApplication(false, mInstrumentation);
				...
        if (activity != 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方法
            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);
            ...
            int theme = r.activityInfo.getThemeResource();
            if (theme != 0) {
                //设置主题
                activity.setTheme(theme);
            }
            ...
            //调用Activity的onCreate方法
            if (r.isPersistable()) {
                mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
            } else {
                mInstrumentation.callActivityOnCreate(activity, r.state);
            }
            ...
            r.activity = activity;
            ...
            //设置Activity生命周期状态为ON_CREATE
            r.setState(ON_CREATE);
            ...
        }
}

performLaunchActivity方法中首先通过ActivityClientRecord获取activity信息,然后就是通过ClassLoader和反射创建activity实例,接着再调用activity的attach方法,然后设置activity的主题啊等一些信息,最后再调用Activity的onCreate方法并将生命周期状态记录为ON_CREATE。

activity的attach方法调用

我们先来简单看看activity.attach方法:

//Activity.java
@UnsupportedAppUsage
final void attach(Context context, ActivityThread aThread,
                  Instrumentation instr, IBinder token, int ident,
                  Application application, Intent intent, ActivityInfo info,
                  CharSequence title, Activity parent, String id,
                  NonConfigurationInstances lastNonConfigurationInstances,
                  Configuration config, String referrer, IVoiceInteractor voiceInteractor,
                  Window window, ActivityConfigCallback activityConfigCallback, IBinder assistToken) {
    ...
    //创建PhoneWindow并赋值给mWindow
    mWindow = new PhoneWindow(this, window, activityConfigCallback);
    mWindow.setWindowControllerCallback(mWindowControllerCallback);
    mWindow.setCallback(this);
    mWindow.setOnWindowDismissedCallback(this);
    mWindow.getLayoutInflater().setPrivateFactory(this);
    if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {
        mWindow.setSoftInputMode(info.softInputMode);
    }
    if (info.uiOptions != 0) {
        mWindow.setUiOptions(info.uiOptions);
    }
    ...
    mWindow.setWindowManager(
        (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
        mToken, mComponent.flattenToString(),
        (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
    if (mParent != null) {
        mWindow.setContainer(mParent.getWindow());
    }
    mWindowManager = mWindow.getWindowManager();
    mCurrentConfig = config;
    ...
}

attach方法里面主要是创建和配置PhoneWindow。在这里不细聊attach方法。

activity的onCreate方法调用

我们继续看activity的onCreate方法的调用,接着上面mInstrumentation.callActivityOnCreate方法看:

//Instrumentation.java
public void callActivityOnCreate(Activity activity, Bundle icicle) {
    //做一些准备工作
    prePerformCreate(activity);
    //真正执行Activity的onCreate
    activity.performCreate(icicle);
    postPerformCreate(activity);
}

我们直接看activity.performCreate(icicle)方法,这个方法在Activity中:

//Activity.java
final void performCreate(Bundle icicle) {
    //调用下面的重载方法
    performCreate(icicle, null);
}

@UnsupportedAppUsage
final void performCreate(Bundle icicle, PersistableBundle persistentState) {
    dispatchActivityPreCreated(icicle);
    mCanEnterPictureInPicture = true;
    ...
    //此处真正调用了Activity的onCreate生命周期方法
    if (persistentState != null) {
        onCreate(icicle, persistentState);
    } else {
        onCreate(icicle);
    }
}

至此Activity的创建和onCreate生命周期方法的调用终于是结束了,再不结束人要狗头了…

好啦,看完之后伙伴们可以自行把源码跟着走一遍整理一下思维,感谢观看!

举报

相关推荐

0 条评论