Sike Android_App startup (startup process including Activity)

1 Introduction

Activity is the daily development of the most common components, the system gave us a lot of packages, so we usually use is particularly simple, very smooth, but have you ever wondered how to start an Activity within the system is it? Activity Objects how to create, and how did life cycle callback method? by learning the underlying works, is the gateway to a senior engineer, we must know ourselves to the principles of Activity started in order to deal with each in the usual development kinds of diseases. This paper is the main process Activity start the process of talks, the purpose is to give us an emotional understanding, not deep buckle details of the code, you can have significance for the development of the upper. unless ROM development, and that the underlying details or requires attention.

Spots: ActivityManagerService (hereinafter referred to as AMS) manages the start of the four components, switches, scheduling and management and scheduling work application process, Android is very very core of AMS services and communication is needed across the process.

ps: This article is an example API 28

1.1 briefly explain the main classes

  • Instrumentation

Instrumentation is instantiated before any application's code runs, it can allow you to monitor all interactive applications and systems. It also constructed Application, building Activity, and will go through the life cycle of this object to execute.

  • ActivityManagerService

Android core services, referred to as AMS, is responsible for scheduling each application process, management of the four components. IActivityManager implements the interface, the application process by calling the system service Binder mechanisms.

  • LaunchActivityItem

Corresponding to the object is a message, when the message is received ActivityThread to start the Activity. After receiving the message performs the execute method starts activity.

  • ActivityThread

Application of the main thread inlet program. Open loop circulating in the main process continually receives the message, processing tasks.

2. Start the application process

About 2.1 Launcher

Launcher, which is the familiar Android desktop, it is actually a APP. The APP just a little bit special, special is that it is the first system boot after the start of the APP, the APP and resident in the system, will not be killed dead, a user press the home button will return to the desktop (back to the APP). put a lot of our own installation or system comes with APP table above, we can open the application by clicking this shortcut applications. currently Launcher Android native version is Launcher3. the mentioned below Launcher.javais an Activity Launcher3 in. Activity in the shortcut icon placed in each application.

2.2 Start the application source code analysis

We click on the shortcut, Launcher Activity of this method will be called onClick

public void onClick(View v) {
    ......
    Object tag = v.getTag();
    if (tag instanceof ShortcutInfo) {
        //点击的是快捷方式->onClickAppShortcut
        onClickAppShortcut(v);
    }
    .....
}

protected void onClickAppShortcut(final View v) {
    ....
    // Start activities
    startAppShortcutOrInfoActivity(v);
}

private void startAppShortcutOrInfoActivity(View v) {
    //将启动信息放在了点击View的tag里面
    ItemInfo item = (ItemInfo) v.getTag();
    // 应用程序安装的时候根据 AndroidManifest.xml 由 PackageManagerService 解析并保存的
    Intent intent;
    if (item instanceof PromiseAppInfo) {
        PromiseAppInfo promiseAppInfo = (PromiseAppInfo) item;
        intent = promiseAppInfo.getMarketIntent();
    } else {
        intent = item.getIntent();
    }
    
    boolean success = startActivitySafely(v, intent, item);
    ....
}

public boolean startActivitySafely(View v, Intent intent, ItemInfo item) {
    ......
    // Prepare intent
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    ......
    // Could be launching some bookkeeping activity
    startActivity(intent, optsBundle);
    ......
}

In dealing with the click event, after onClickAppShortcut method calls startAppShortcutOrInfoActivity method to obtain Intent information, then call startActivitySafely method, which calls startActivity method we use regularly. Because Launcher class is an Activity, so tune startActivity method for granted. Call here startActivity method will start the first of Activity APP.

3. Start Activity

For example in source API 28

3.1 boot process

Activity came to the startActivity method, which ultimately calls startActivityForResult ()

public void startActivityForResult(@RequiresPermission Intent intent, int requestCode,
        @Nullable Bundle options) {
    //mMainThread是ActivityThread,mMainThread.getApplicationThread()是获取ApplicationThread
    Instrumentation.ActivityResult ar =
        mInstrumentation.execStartActivity(
            this, mMainThread.getApplicationThread(), mToken, this,
            intent, requestCode, options);
}

startActivityForResult which calls execStartActivity method Instrumentation, where mMainThread is ActivityThread (from here started an application), mMainThread.getApplicationThread () is to obtain ApplicationThread.ApplicationThread is ActivityThread inner class, it will be introduced to a little later.

public ActivityResult execStartActivity(
        Context who, IBinder contextThread, IBinder token, Activity target,
        Intent intent, int requestCode, Bundle options) {
    //1. 将ApplicationThread转为IApplicationThread
    IApplicationThread whoThread = (IApplicationThread) contextThread;
    
    //2. 获取AMS实例,调用startActivity方法
    int result = ActivityManager.getService()
        .startActivity(whoThread, who.getBasePackageName(), intent,
                intent.resolveTypeIfNeeded(who.getContentResolver()),
                token, target != null ? target.mEmbeddedID : null,
                requestCode, 0, null, options);
    checkStartActivityResult(result, intent);

    return null;
}

IApplicationThread is a Binder interface that inherits from IInterface.ApplicationThread inherited IApplicationThread.Stub, realized IApplicationThread, it can turn into IApplicationThread.

Then it is to get AMS instance, call startActivity method of AMS.

public static IActivityManager getService() {
    return IActivityManagerSingleton.get();
}

private static final Singleton<IActivityManager> IActivityManagerSingleton =
        new Singleton<IActivityManager>() {
            @Override
            protected IActivityManager create() {
                //1. 获取服务的Binder对象
                final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                //2. aidl 获取AMS
                final IActivityManager am = IActivityManager.Stub.asInterface(b);
                return am;
            }
        };

ServiceManager Andrews is an important class for managing all system services, maintains binder communications services and clients. Binder object is returned, used to communicate between applications and system services.

Here we continue to enter startActivity method of AMS

@Override
public final int startActivity(IApplicationThread caller, String callingPackage,
        Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
        int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
    return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
            resultWho, requestCode, startFlags, profilerInfo, bOptions,
            UserHandle.getCallingUserId());
}
@Override
public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
        Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
        int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
    return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
            resultWho, requestCode, startFlags, profilerInfo, bOptions, userId,
            true /*validateIncomingUser*/);
}

public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
        Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
        int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
        boolean validateIncomingUser) {

    // TODO: Switch to user app stacks here.
    return mActivityStartController.obtainStarter(intent, "startActivityAsUser")
            .setCaller(caller)
            .setCallingPackage(callingPackage)
            .setResolvedType(resolvedType)
            .setResultTo(resultTo)
            .setResultWho(resultWho)
            .setRequestCode(requestCode)
            .setStartFlags(startFlags)
            .setProfilerInfo(profilerInfo)
            .setActivityOptions(bOptions)
            .setMayWait(userId)
            .execute();

}

AMS is startActivity method calls startActivityAsUser AMS method, and then call another startActivityAsUser method. Finally came a string of chained calls, finally will come to execute the method ActivityStarter.

int execute() {
    return startActivityMayWait(mRequest.caller, mRequest.callingUid,
            mRequest.callingPackage, mRequest.intent, mRequest.resolvedType,
            mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo,
            mRequest.resultWho, mRequest.requestCode, mRequest.startFlags,
            mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig,
            mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId,
            mRequest.inTask, mRequest.reason,
            mRequest.allowPendingRemoteAnimationRegistryLookup);
}
private int startActivityMayWait(IApplicationThread caller, int callingUid,
        String callingPackage, Intent intent, String resolvedType,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        IBinder resultTo, String resultWho, int requestCode, int startFlags,
        ProfilerInfo profilerInfo, WaitResult outResult,
        Configuration globalConfig, SafeActivityOptions options, boolean ignoreTargetSecurity,
        int userId, TaskRecord inTask, String reason,
        boolean allowPendingRemoteAnimationRegistryLookup) {
    ......
    int res = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo,
            voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid,
            callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options,
            ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason,
            allowPendingRemoteAnimationRegistryLookup);
    ......
}

private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
        String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
        String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
        SafeActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified,
        ActivityRecord[] outActivity, TaskRecord inTask, String reason,
        boolean allowPendingRemoteAnimationRegistryLookup) {
    ......
    mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
            aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
            callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
            options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
            inTask, allowPendingRemoteAnimationRegistryLookup);
    ......
}

private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent,
        String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid,
        String callingPackage, int realCallingPid, int realCallingUid, int startFlags,
        SafeActivityOptions options,
        boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity,
        TaskRecord inTask, boolean allowPendingRemoteAnimationRegistryLookup) {
    ......
    return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags,
            true /* doResume */, checkedOptions, inTask, outActivity);
}

ActivityStarter execute method will continue to call startActivityMayWait method .startActivityMayWait going to call startActivity method, and then call another startActivity method. StartActivity then is to call another method,

I have to say, the parameters of these methods can be really long ah ,,,, may be due to historical reasons for it.

private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
            IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
            int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
            ActivityRecord[] outActivity) {
    ......
    result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
                startFlags, doResume, options, inTask, outActivity);
    ......
}

private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
        IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
        int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
        ActivityRecord[] outActivity) {
    .......
    mSupervisor.resumeFocusedStackTopActivityLocked(mTargetStack, mStartActivity, mOptions);

    return START_SUCCESS;
}

Finally do not call startActivity method, and call startActivityUnchecked method, which calls resumeFocusedStackTopActivityLocked method of ActivityStackSupervisor

 boolean resumeFocusedStackTopActivityLocked(
        ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
    ......
    return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
    ......
}

targetStack is ActivityStack, calls resumeTopActivityUncheckedLocked method ActivityStack then calls resumeTopActivityInnerLocked method.

boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
    ......
    result = resumeTopActivityInnerLocked(prev, options);
    .....
    return result;
}


private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
    ......
    mStackSupervisor.startSpecificActivityLocked(next, true, false);
    ......
    return true;
}

And then will return to startSpecificActivityLocked method of ActivityStackSupervisor


void startSpecificActivityLocked(ActivityRecord r,
            boolean andResume, boolean checkConfig) {
    ....
    //进程存在则启动
    if (app != null && app.thread != null) {
        realStartActivityLocked(r, app, andResume, checkConfig);
        return;
    }
    
    //进程不存在则创建
    mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
            "activity", r.intent.getComponent(), false, false, true);
}

Here will determine what process exists, and if it does not exist create it. MService here is the AMS, the AMS will call startProcessLocked method.

final ProcessRecord startProcessLocked(String processName,
            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
        String hostingType, ComponentName hostingName, boolean allowWhileBooting,
        boolean isolated, boolean keepIfLarge) {
    return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
            hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
            null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
            null /* crashHandler */);
}

final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
        boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
        boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
        String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
    ......
    final boolean success = startProcessLocked(app, hostingType, hostingNameStr, abiOverride);
    ......
}

private final boolean startProcessLocked(ProcessRecord app,
        String hostingType, String hostingNameStr, String abiOverride) {
    return startProcessLocked(app, hostingType, hostingNameStr,
            false /* disableHiddenApiChecks */, abiOverride);
}

private final boolean startProcessLocked(ProcessRecord app, String hostingType,
            String hostingNameStr, boolean disableHiddenApiChecks, String abiOverride) {
    ......
    return startProcessLocked(hostingType, hostingNameStr, entryPoint, app, uid, gids,
            runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,
            startTime);
    ......
}

private boolean startProcessLocked(String hostingType, String hostingNameStr, String entryPoint,
            ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
            String seInfo, String requiredAbi, String instructionSet, String invokeWith,
            long startTime) {
    ......
    final ProcessStartResult startResult = startProcess(app.hostingType, entryPoint,
            app, app.startUid, gids, runtimeFlags, mountExternal, app.seInfo,
            requiredAbi, instructionSet, invokeWith, app.startTime);
    ......
}

private ProcessStartResult startProcess(String hostingType, String entryPoint,
        ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal,
        String seInfo, String requiredAbi, String instructionSet, String invokeWith,
        long startTime) {
    ......
    startResult = Process.start(entryPoint,
            app.processName, uid, uid, gids, runtimeFlags, mountExternal,
            app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
            app.info.dataDir, invokeWith,
            new String[] {PROC_START_SEQ_IDENT + app.startSeq});
    ......
}

Here AMS calls the many layers startProcessLocked, eventually calling startProcess method, and then call the start method Process.

public static final ProcessStartResult start(final String processClass,
                              final String niceName,
                              int uid, int gid, int[] gids,
                              int debugFlags, int mountExternal,
                              int targetSdkVersion,
                              String seInfo,
                              String abi,
                              String instructionSet,
                              String appDataDir,
                              String[] zygoteArgs) {
    return startViaZygote(processClass, niceName, uid, gid, gids,
            debugFlags, mountExternal, targetSdkVersion, seInfo,
            abi, instructionSet, appDataDir, zygoteArgs);
}

private static ProcessStartResult startViaZygote(final String processClass,
                              final String niceName,
                              final int uid, final int gid,
                              final int[] gids,
                              int debugFlags, int mountExternal,
                              int targetSdkVersion,
                              String seInfo,
                              String abi,
                              String instructionSet,
                              String appDataDir,
                              String[] extraArgs)
                              throws ZygoteStartFailedEx {
    ......           
    //如果需要,则打开Socket,用来和zygote通讯
    return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
}

private static Process.ProcessStartResult zygoteSendArgsAndGetResult(
        ZygoteState zygoteState, ArrayList<String> args)
        throws ZygoteStartFailedEx {
    ......
    final BufferedWriter writer = zygoteState.writer;
    final DataInputStream inputStream = zygoteState.inputStream;

    writer.write(Integer.toString(args.size()));
    writer.newLine();

    for (int i = 0; i < sz; i++) {
        String arg = args.get(i);
        writer.write(arg);
        writer.newLine();
    }

    writer.flush();

    // Should there be a timeout on this?
    Process.ProcessStartResult result = new Process.ProcessStartResult();

    // Always read the entire result from the input stream to avoid leaving
    // bytes in the stream for future process starts to accidentally stumble
    // upon.
    result.pid = inputStream.readInt();
    result.usingWrapper = inputStream.readBoolean();

    if (result.pid < 0) {
        throw new ZygoteStartFailedEx("fork() failed");
    }
    return result;
    ......
}

Previous got zygoteState now communicate first transmission process to zygote.zygote get past these parameters will give you that you need to create a parameter by a write method then returns the results read out by the read. Here is the process created by fork APP process .zygote a child process.

3.2 Start the main thread

Entry process, which is the main method is ActivityThread we know, this method is very clear ideas, very simple. Of course, there is also the main thread of the entrance.

public static void main(String[] args) {
    
    //分析1 主线程Looper安排上
    Looper.prepareMainLooper();

    ......
    //分析2  
    ActivityThread thread = new ActivityThread();
    thread.attach(false, startSeq);
    
    //分析3 死循环,接收主线程上的消息
    Looper.loop();

    throw new RuntimeException("Main thread loop unexpectedly exited");
}

1 and 3 analysis in which the analysis in all Sike Android_Handler mechanism you need to know has been described in detail to explain, not repeat them here.

Let's analyze point 2:

final ApplicationThread mAppThread = new ApplicationThread();
private void attach(boolean system, long startSeq) {
    ......
    if (!system) {
        //这一步是获取AMS实例,上面已经出现过
        final IActivityManager mgr = ActivityManager.getService();
        //然后跨进程通信
        mgr.attachApplication(mAppThread, startSeq);
    } 
}

By acquiring AMS, cross-process communication, a method of AMS calls attachApplication

public final void attachApplication(IApplicationThread thread, long startSeq) {
    synchronized (this) {
        int callingPid = Binder.getCallingPid();
        final int callingUid = Binder.getCallingUid();
        final long origId = Binder.clearCallingIdentity();
        attachApplicationLocked(thread, callingPid, callingUid, startSeq);
        Binder.restoreCallingIdentity(origId);
    }
}

@GuardedBy("this")
private final boolean attachApplicationLocked(IApplicationThread thread,
        int pid, int callingUid, long startSeq) {

    ......
    //这里的thread就是ActivityThread中的ApplicationThread
    thread.bindApplication(processName, appInfo, providers,
            app.instr.mClass,
            profilerInfo, app.instr.mArguments,
            app.instr.mWatcher,
            app.instr.mUiAutomationConnection, testMode,
            mBinderTransactionTrackingEnabled, enableTrackAllocation,
            isRestrictedBackupMode || !normalMode, app.persistent,
            new Configuration(getGlobalConfiguration()), app.compat,
            getCommonServicesLocked(app.isolated),
            mCoreSettingsObserver.getCoreSettingsLocked(),
            buildSerial, isAutofillCompatEnabled);

    // See if the top visible activity is waiting to run in this process...
    //看一下是不是有需要运行的Activity
    if (normalMode) {
        try {
            if (mStackSupervisor.attachApplicationLocked(app)) {
                didSomething = true;
            }
        } catch (Exception e) {
            Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
            badApp = true;
        }
    }

    ......
    return true;
}

There are two points to note

  • The first is to call across process attachApplication method by AMS, and then continue to call attachApplicationLocked method, however, but cross-process calls bindApplication method ActivityThread in mAppThread (ApplicationThread) in. Are instinctively create Application
  • The second is to open the first Activity, calling attachApplicationLocked method of ActivityStackSupervisor.

3.3 Creating Application

Let's look at ApplicationThread method of bindApplication

public final void bindApplication(String processName, ApplicationInfo appInfo,
        List<ProviderInfo> providers, 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, boolean autofillCompatibilityEnabled) {

    AppBindData data = new AppBindData();
    .......
    //主要就是发送一个消息
    sendMessage(H.BIND_APPLICATION, data);
}

void sendMessage(int what, Object obj) {
    sendMessage(what, obj, 0, 0, false);
}

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是一个Handler,发送了一个消息
    mH.sendMessage(msg);
}


 class H extends Handler {
        //先看看这个Handler的部分消息名称,一看就知道是干嘛的,什么绑定Application,绑定Service,停止Service什么的.这个Handler和这些组件的启动停止什么的,关系非常大.
        //其实这个Handler在API 28之前的时候消息更多,(API 28只是融合了一下,多个消息变成1个消息,还是会走到这个Handler),之前Activity的各种生命周期回调都有对应的消息名称里.现在是融合了.
        public static final int BIND_APPLICATION        = 110;
        public static final int EXIT_APPLICATION        = 111;
        public static final int RECEIVER                = 113;
        public static final int CREATE_SERVICE          = 114;
        public static final int SERVICE_ARGS            = 115;
        public static final int STOP_SERVICE            = 116;
        public static final int CONFIGURATION_CHANGED   = 118;
        public static final int CLEAN_UP_CONTEXT        = 119;
        public static final int GC_WHEN_IDLE            = 120;
        public static final int BIND_SERVICE            = 121;
        public static final int RELAUNCH_ACTIVITY = 160;
}

In ApplicationThread the bindApplication will call sendMessage (this method is ActivityThread is because ApplicationThread is an internal class can be invoked) method to send a message, receive a message via H (This class is ActivityThread inner classes) that Handler. Because ApplicationThread Binder is running in the thread pool, so it is necessary to switch to the main thread to do some operation on the UI, such as open Activity or something. BIND_APPLICATION eventually came at news of H

public void handleMessage(Message msg) {
    switch (msg.what) {
        case BIND_APPLICATION:
            AppBindData data = (AppBindData)msg.obj;
            handleBindApplication(data);
            break;
        ......
    }
}

private void handleBindApplication(AppBindData data) {

    // Continue loading instrumentation.
    if (ii != null) {
        ApplicationInfo instrApp;
        instrApp = getPackageManager().getApplicationInfo(ii.packageName, 0,
                UserHandle.myUserId());
        //构建ContextImpl
        final ContextImpl instrContext = ContextImpl.createAppContext(this, pi);
        //获取其classLoader
        final ClassLoader cl = instrContext.getClassLoader();
        //构建Instrumentation 
        mInstrumentation = (Instrumentation)
            cl.loadClass(data.instrumentationName.getClassName()).newInstance();
    } else {
        mInstrumentation = new Instrumentation();
        mInstrumentation.basicInit(this);
    }

    Application app;
    // If the app is being launched for full backup or restore, bring it up in
    // a restricted environment with the base application class.
    //构建Application
    app = data.info.makeApplication(data.restrictedBackupMode, null);

    //调用Application的onCreate方法
    mInstrumentation.callApplicationOnCreate(app);
}

//sources/android-28/android/app/LoadedApk.java#makeApplication
public Application makeApplication(boolean forceDefaultAppClass,
        Instrumentation instrumentation) {
    //注意,如果Application已经初始化,那么就不重新初始化了  
    if (mApplication != null) {
        return mApplication;
    }

    Application app = null;

    String appClass = mApplicationInfo.className;
    if (forceDefaultAppClass || (appClass == null)) {
        appClass = "android.app.Application";
    }
    //构建Application
    app = mActivityThread.mInstrumentation.newApplication(
            cl, appClass, appContext);
    appContext.setOuterContext(app);

    return app;
}

//sources/android-28/android/app/Instrumentation.java#newApplication
public Application newApplication(ClassLoader cl, String className, Context context)
        throws InstantiationException, IllegalAccessException, 
        ClassNotFoundException {
    //通过反射构建Application
    Application app = getFactory(context.getPackageName())
            .instantiateApplication(cl, className);
    //赋值Context
    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();
}

In this process H BIND_APPLICATION Handler in this message, the first target is constructed by Instrumentation ClassLoader loading, then the newApplication Instrumentation LoadedApk calling method (mInstrumentation strange here, why not directly call build out newApplication method ..), by way of loadClass Application will be created out of the object, and then calls the onCreate method Application of the life cycle.

3.4 Creating Activity

Here attachApplicationLocked the way we continue ActivityStackSupervisor

boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
    ......
    realStartActivityLocked(activity, app,top == activity, true);
    ......
}

final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
            boolean andResume, boolean checkConfig) throws RemoteException {
    ......
    // Create activity launch transaction.
    //创建活动启动事务。
    final ClientTransaction clientTransaction = ClientTransaction.obtain(app.thread,
            r.appToken);
    //构建LaunchActivityItem对象,并传入clientTransaction中,用作callback
    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));

    // Schedule transaction.
    //执行事务  这里getLifecycleManager获取的是ClientLifecycleManager
    mService.getLifecycleManager().scheduleTransaction(clientTransaction);
    ......
}

//ClientLifecycleManager#scheduleTransaction
void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
    //继续深入
    transaction.schedule();
}

//ClientTransaction#schedule
public void schedule() throws RemoteException {
    //这里的mClient是ApplicationThread
    mClient.scheduleTransaction(this);
}

//ApplicationThread#scheduleTransaction
@Override
public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
    //ActivityThread是继承自ClientTransactionHandler的,scheduleTransaction方法在ClientTransactionHandler里面
    ActivityThread.this.scheduleTransaction(transaction);
}

//ClientTransactionHandler#scheduleTransaction
void scheduleTransaction(ClientTransaction transaction) {
    transaction.preExecute(this);
    //注意啦,这里向ActivityThread里面的H这个Handler发送了一个EXECUTE_TRANSACTION的消息,并且将ClientTransaction对象也传了进去
    sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
//ClientTransactionHandler#sendMessage   这个方法是抽象方法,是在ActivityThread里面实现的,当然是给H这个Handler发消息啦
abstract void sendMessage(int what, Object obj);

In Android8.0 in a) relevant data encapsulated by ApplicationThread.scheduleLaunchActivity (, and transmitted by calling sendMessage ActivityThread class ().
But in Android9.0, the introduction of ClientLifecycleManager and ClientTransactionHandler to assist management Activity lifecycle. The life cycle is equivalent to abstract out a life cycle replaced by an object.

By tossing the above method invocation, and finally we came to scheduleTransaction method ClientTransactionHandler, and then sends a to ActivityThread the H EXECUTE_TRANSACTIONmessages
in API 28 inside, ActivityThread of H this Handler which has gone what those before LAUNCH_ACTIVITY, PAUSE_ACTIVITY, RESUME_ACTIVITYmessages, to be replaced is EXECUTE_TRANSACTIONthis a message.

//ActivityThread里面的H  
private final TransactionExecutor mTransactionExecutor = new TransactionExecutor(this);  //这里传入的是ClientTransactionHandler对象(即ActivityThread),ClientTransactionHandler是ActivityThread的父类
class H extends Handler {
    public void handleMessage(Message msg) {
        switch (msg.what) {
            case EXECUTE_TRANSACTION:
                //首先取出ClientTransaction对象
                final ClientTransaction transaction = (ClientTransaction) msg.obj;
                //将ClientTransaction传入execute方法
                mTransactionExecutor.execute(transaction);
        }
    }
}

//TransactionExecutor#execute
public void execute(ClientTransaction transaction) {
    final IBinder token = transaction.getActivityToken();
    log("Start resolving transaction for client: " + mTransactionHandler + ", token: " + token);

    executeCallbacks(transaction);

    executeLifecycleState(transaction);
    mPendingActions.clear();
    log("End resolving transaction");
}

//TransactionExecutor#executeCallbacks
public void executeCallbacks(ClientTransaction transaction) {
    //取出ClientTransaction对象里面的callback,即上面的LaunchActivityItem
    final List<ClientTransactionItem> callbacks = transaction.getCallbacks();

    final int size = callbacks.size();
    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());

        item.execute(mTransactionHandler, token, mPendingActions);
        item.postExecute(mTransactionHandler, token, mPendingActions);
    }
}

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

In ActivityThread in the EXECUTE_TRANSACTIONmessage, perform the execute method TransactionExecutor objects, which we then performed executeCallbacks methods to come up with callback ClientTransaction objects inside executeCallbacks methods that exist above go LaunchActivityItem.
Then perform LaunchActivityItem execute method, call the method is handleLaunchActivity ActivityThread, and finally came to the familiar links.

//ActivityThread#handleLaunchActivity
@Override
public Activity handleLaunchActivity(ActivityClientRecord r,
        PendingTransactionActions pendingActions, Intent customIntent) {
    .....
    //终于要开始调用performLaunchActivity这个熟悉的方法了
    final Activity a = performLaunchActivity(r, customIntent);
    ......
}

//ActivityThread#performLaunchActivity
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
    ......
    ContextImpl appContext = createBaseContextForActivity(r);
    Activity activity = null;

    //获取ClassLoader
    java.lang.ClassLoader cl = appContext.getClassLoader();
    
    //通过(Activity) cl.loadClass(className).newInstance()创建
    //重点来啦:Activity是在ActivityThread的performLaunchActivity方法中用ClassLoader类加载器创建出来的。
    activity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);
    
    //底层也是通过反射构建Application,如果已经构建则不会重复构建,毕竟一个进程只能有一个Application
    Application app = r.packageInfo.makeApplication(false, mInstrumentation);

    if (activity != null) {
        Window window = null;
        appContext.setOuterContext(activity);
        //在这里实例化了PhoneWindow,并将该Activity设置为PhoneWindow的Callback回调,还初始化了WindowManager
        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);
                
        //间接调用了Activity的performCreate方法,间接调用了Activity的onCreate方法.
        mInstrumentation.callActivityOnCreate(activity, r.state);
        
        //这里和上面onCreate过程差不多,调用Activity的onStart方法
        if (!r.activity.mFinished) {
            activity.performStart();
            r.stopped = false;
        }
        ....
    }

    return activity;
}

This process is more familiar with, focusing on: Activity is created by performLaunchActivity out in ActivityThread method of ClassLoader class loader. Will call onCreate method and the method Activity onStart after created.

Drawing on View after creation out behind Activity, look here

reference

Reproduced in: https: //www.jianshu.com/p/2f5b953246aa

Guess you like

Origin blog.csdn.net/weixin_34320724/article/details/91336789