美文网首页Android进化
Android 系统分析进程及Activity启动分析

Android 系统分析进程及Activity启动分析

作者: 锄禾豆 | 来源:发表于2019-11-12 09:25 被阅读0次

    提问:

    1.系统很多自启应用,是怎么启动的,例如,systemUI、桌面、persist属性的apk?

    2.为什么分析应用进程的启动,从ActivityThread.java开始,从哪里看出来用的是它?

    前言:

    a.使用8.1系统代码分析

    b.各种代码集合如下:

    frameworks/base/core/java/android/app

    Instrumentation.java

    LoadedApk.java

    ActivityThread.java

    ContextImpl.java

    frameworks/base/core/java/android/os

    Process.java

    ZygoteProcess.java

    frameworks/base/core/java/android/internal/os

    ZygoteInit.java

    ZygoteConnection.java

    RuntimeInit.java

    ZygoteServer.java

    frameworks/base/services/core/java/com/android/server/am/

    ActivityManagerService.java

    ActivityStackSupervisor.java

    ActivityStack.java

    TaskRecord.java

    ActivityRecord.java

    一、从桌面启动某一个apk到AMS

    ContextImpl.java
    startActivity-->Instrumentation.execStartActivity
    
    Instrumentation.java
    public ActivityResult execStartActivity(
                Context who, IBinder contextThread, IBinder token, Activity target,
                Intent intent, int requestCode, Bundle options) {
            IApplicationThread whoThread = (IApplicationThread) contextThread;
            ······
           int result = ActivityManager.getService()
                    .startActivity(whoThread, who.getBasePackageName(), intent,//1
                            intent.resolveTypeIfNeeded(who.getContentResolver()),
                            token, target != null ? target.mEmbeddedID : null,
                            requestCode, 0, null, options);
           ······
    }
    注解1:
    a.whoThread是一个IApplicationThread,也就是说,后面跨进程通信时,它是被用来回调的方法.
    这个具体的实现类是ActivityThread的内部类ApplicationThread。
    
    b.ActivityManager.getService(),其实就是ActivityManagerService。注意,此单例模式的实现方式很棒,后面可以被采用,具体如下:
    public static IActivityManager getService() {
            return IActivityManagerSingleton.get();
    }
    
    private static final Singleton<IActivityManager> IActivityManagerSingleton =
                new Singleton<IActivityManager>() {
                    @Override
                    protected IActivityManager create() {
                        final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                        final IActivityManager am = IActivityManager.Stub.asInterface(b);
                        return am;
                    }
     };
     
     Singleton.java,这个类封装的很灵活。其实,系统中有很多这种很灵活的封装手法,例如SystemServiceRegistry注册服务中涉及到
     public abstract class Singleton<T> {
        private T mInstance;
    
        protected abstract T create();
    
        public final T get() {
            synchronized (this) {
                if (mInstance == null) {
                    mInstance = create();
                }
                return mInstance;
            }
        }
    }
    
    ActivityManagerService.java
    startActivity-->startActivityAsUser
    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 mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
                    resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
                    profilerInfo, null, null, bOptions, false, userId, null, "startActivityAsUser");
    }
    
    ActivityStarter.java
    final int startActivityMayWait(IApplicationThread caller ······) {//1
            ······
            int res = startActivityLocked(caller, intent, ephemeralIntent, resolvedType,
                        aInfo, rInfo, voiceSession, voiceInteractor,
                        resultTo, resultWho, requestCode, callingPid,
                        callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
                        options, ignoreTargetSecurity, componentSpecified, outRecord, inTask,
                        reason);
             ······
    }
    注解1:这个方法巨长,怎么找到关键的方法呢?其实,这是一种命名方式,代码写的棒的,一般会把相似方法,进行同名命名。
    另外,也可以直接从方法后面往前找。
    
    int startActivityLocked(IApplicationThread caller ······) {
          ······
          mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType,
                    aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode,
                    callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags,
                    options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord,
                    inTask);
          ······
    }
    
    private int startActivity(IApplicationThread caller ······) {
        ······
        ProcessRecord callerApp = null;
        if (caller != null) {
                callerApp = mService.getRecordForAppLocked(caller);
                ······
        }
        ······
        ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid,
                    callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
                    resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
                    mSupervisor, options, sourceRecord);
        ······
       return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true,
                    options, inTask, outActivity);//1
    }
    注解1:此方法中没有了caller,那caller去哪里了呢?仔细看列出来的函数,先放进ProcessRecord,再被r所包含。
    
     private int startActivity(final ActivityRecord r, ActivityRecord sourceRecord,
                IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
                int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask,
                ActivityRecord[] outActivity) {
            int result = START_CANCELED;
            try {
                ······
                result = startActivityUnchecked(r, sourceRecord, voiceSession, voiceInteractor,
                        startFlags, doResume, options, inTask, outActivity);
            } 
            ······
            return result;
    }
    
    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);
             ······
    }
    
    
    ActivityStackSupervisor.java
    boolean resumeFocusedStackTopActivityLocked(
                ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
    
            if (!readyToResume()) {
                return false;
            }
    
            if (targetStack != null && isFocusedStack(targetStack)) {
                return targetStack.resumeTopActivityUncheckedLocked(target, targetOptions);
            }
            ·······
    }
    
    ActivityStack.java
    boolean resumeTopActivityUncheckedLocked(ActivityRecord prev, ActivityOptions options) {
            ······
            result = resumeTopActivityInnerLocked(prev, options);
            ······
    }
    private boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
        ······
        mStackSupervisor.startSpecificActivityLocked(next, true, true);
        ······
    }
    
    ActivityStackSupervisor.java
    void startSpecificActivityLocked(ActivityRecord r,
                boolean andResume, boolean checkConfig) {
            // Is this activity's application already running?
            ProcessRecord app = mService.getProcessRecordLocked(r.processName,
                    r.info.applicationInfo.uid, true);
    
            r.getStack().setLaunchTime(r);
    
            if (app != null && app.thread != null) {//1
                try {
                    if ((r.info.flags&ActivityInfo.FLAG_MULTIPROCESS) == 0
                            || !"android".equals(r.info.packageName)) {
                        // Don't add this if it is a platform component that is marked
                        // to run in multiple processes, because this is actually
                        // part of the framework so doesn't make sense to track as a
                        // separate apk in the process.
                        app.addPackage(r.info.packageName, r.info.applicationInfo.versionCode,
                                mService.mProcessStats);
                    }
                    realStartActivityLocked(r, app, andResume, checkConfig);//2
                    return;
                } catch (RemoteException e) {
                    Slog.w(TAG, "Exception when starting activity "
                            + r.intent.getComponent().flattenToShortString(), e);
                }
    
                // If a dead object exception was thrown -- fall through to
                // restart the application.
            }
    
            mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                    "activity", r.intent.getComponent(), false, false, true);//3
        }
    注解1:如果app进程已经存在,就进行realStartActivityLocked
    注解2:如果app进程不在,就进行启动进程的动作:mService.startProcessLocked
    

    总结,分析上面的代码逻辑,发现代码走到AMS时,出现ActivityStarter.java、ActivityStackSupervisor.java、
    ActivityStack.java、ActivityRecord.java、TaskRecord.java,接着就是绕来绕去的调用。

    补充学习

    重点参考学习:

    https://blog.csdn.net/u011810352/article/details/79378632

    对于ActivityRecord、TaskRecord、ActivityStack、ActivityStackSupervisor的关系,我们用一张图表示:

    APK启动模式.png

    我们结合Activity启动模式,就容易理解其中的各种意思:

    Standard 标准模式、SingleTop 栈顶复用模式、SingleTask 栈内复用模式、SingleInstance 单实例模式

    二、从AMS通知Zygote进程启动apk进程

    ActivityManagerService.java
    
    private final void startProcessLocked(ProcessRecord app, String hostingType,
                String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
           ······
           boolean isActivityProcess = (entryPoint == null);
           if (entryPoint == null) entryPoint = "android.app.ActivityThread";//1
           ······     
           startResult = Process.start(entryPoint,
                            app.processName, uid, uid, gids, debugFlags, mountExternal,
                            app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
                            app.info.dataDir, invokeWith, entryPointArgs);
           ······         
    }
    注解1:我们一直说,ActivityThread.java是启动应用进程的根,但是从哪里查出是这个类?AMS这里表明了,之后,通过socket发送到Zygote进程,Zygote进程进行执行
    
    Process.java
    public static final ProcessStartResult start(final String processClass ······ ) {
            return zygoteProcess.start(processClass, niceName, uid, gid, gids,
                        debugFlags, mountExternal, targetSdkVersion, seInfo,
                        abi, instructionSet, appDataDir, invokeWith, zygoteArgs);
        }
    
    ZygoteProcess.java
    start-->startViaZygote
    private Process.ProcessStartResult startViaZygote(final String processClass ······) throws ZygoteStartFailedEx {
        ······
        argsForZygote.add(processClass);
        ······
        synchronized(mLock) {
                return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);//1
            }
    }
    
    注解1:关注openZygoteSocketIfNeeded和zygoteSendArgsAndGetResult
    
    先说openZygoteSocketIfNeeded,目的是建立socket通信环境
    private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
        ······
        primaryZygoteState = ZygoteState.connect(mSocket);
        ······
    }
    
    public static ZygoteState connect(String socketAddress) throws IOException {
                DataInputStream zygoteInputStream = null;
                BufferedWriter zygoteWriter = null;
                final LocalSocket zygoteSocket = new LocalSocket();
    
                try {
                    zygoteSocket.connect(new LocalSocketAddress(socketAddress,
                            LocalSocketAddress.Namespace.RESERVED));
    
                    zygoteInputStream = new DataInputStream(zygoteSocket.getInputStream());
    
                    zygoteWriter = new BufferedWriter(new OutputStreamWriter(
                            zygoteSocket.getOutputStream()), 256);
                } catch (IOException ex) {
                    try {
                        zygoteSocket.close();
                    } catch (IOException ignore) {
                    }
    
                    throw ex;
                }
    
                String abiListString = getAbiList(zygoteWriter, zygoteInputStream);
                Log.i("Zygote", "Process: zygote socket " + socketAddress + " opened, supported ABIS: "
                        + abiListString);
    
                return new ZygoteState(zygoteSocket, zygoteInputStream, zygoteWriter,
                        Arrays.asList(abiListString.split(",")));
            }
    
    再说zygoteSendArgsAndGetResult,目的是发送消息到服务端
    private static Process.ProcessStartResult zygoteSendArgsAndGetResult(
                ZygoteState zygoteState, ArrayList<String> args)
                throws ZygoteStartFailedEx {
            //socket通信,将args发送出去
            //args
        }
    
        
    这里重点说一下Socket的服务端:
    Zygote进程是怎么启动Socket进行监听的?
    app_main.cpp
    int main(int argc, char* const argv[])
    {
        ······
        AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
        ······
        bool zygote = false;
    
        ++i;  // Skip unused "parent dir" argument.
        while (i < argc) {
            const char* arg = argv[i++];
            if (strcmp(arg, "--zygote") == 0) {//1
                zygote = true;
                niceName = ZYGOTE_NICE_NAME;
            } 
            ······
        }
        ······
        if (zygote) {
            runtime.start("com.android.internal.os.ZygoteInit", args, zygote);//2
        } 
    }
    注解1:init进程启动Zygote进程是通过init.rc启动,所以,当有--zygote的状态时,代表zygote = true
    注解2:AppRuntime.cpp启动ZygoteInit.java中的main方法。注意:AppRuntime继承AndroidRuntime,AndroidRuntime有start函数
    
    ZygoteInit.java
    public static void main(String argv[]) {
            ZygoteServer zygoteServer = new ZygoteServer();
            ······
            final Runnable caller;//1
            ······
            String socketName = "zygote";
            ······
            zygoteServer.registerServerSocket(socketName);//2
            ······
            caller = zygoteServer.runSelectLoop(abiList);//3
            ······
            // We're in the child process and have exited the select loop. Proceed to execute the
            // command.
            if (caller != null) {
                caller.run();//4
            }
    }
    注解1:caller是一个Runnable,caller由3赋值,4真正执行run
    注解2:Socket服务端进行了注册
    注解3:通过ZygoteServer端获取一个Runable,注意这个Runnable绕了几道。
    注解4:执行caller
    
    ZygoteServer.java
    Runnable runSelectLoop(String abiList) {
            ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
            ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
    
            fds.add(mServerSocket.getFileDescriptor());
            peers.add(null);
    
            while (true) {
                ······
                for (int i = pollFds.length - 1; i >= 0; --i) {
                    ······
                    ZygoteConnection connection = peers.get(i);
                    final Runnable command = connection.processOneCommand(this);//1
                    ······
                    return command;
    
                }
            }
        }
    注解1:执行ZygoteConnection中的processOneCommand
    
    ZygoteConnection.java
    Runnable processOneCommand(ZygoteServer zygoteServer) {
    
            ······
            pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
                    parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
                    parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.instructionSet,
                    parsedArgs.appDataDir);
    
            try {
                if (pid == 0) {//1
                    // in child
                    ······
                    return handleChildProc(parsedArgs, descriptors, childPipeFd);//2
                } else {//3
                    // In the parent. A pid < 0 indicates a failure and will be handled in
                    // handleParentProc.
                    ······
                    handleParentProc(pid, descriptors, serverPipeFd);
                    return null;
                }
            } finally {
                IoUtils.closeQuietly(childPipeFd);
                IoUtils.closeQuietly(serverPipeFd);
            }
    }
    注解1和注解3:如果pid是0,代表是子进程,非0,代表是父进程
    注解2:我们重点看子进程的处理逻辑
    
    private Runnable handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors,
                FileDescriptor pipeFd) {
            ······
            if (parsedArgs.invokeWith != null) {
                WrapperInit.execApplication(parsedArgs.invokeWith,
                        parsedArgs.niceName, parsedArgs.targetSdkVersion,
                        VMRuntime.getCurrentInstructionSet(),
                        pipeFd, parsedArgs.remainingArgs);
    
                // Should not get here.
                throw new IllegalStateException("WrapperInit.execApplication unexpectedly returned");
            } else {
                return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs,
                        null /* classLoader */);
            }
        }
    
    又回到了ZygoteInit.java类
    public static final Runnable zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) {
            ······
            return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
        }
    
    RuntimeInit.java
    protected static Runnable applicationInit(int targetSdkVersion, String[] argv,
                ClassLoader classLoader) {
            ······
            // Remaining arguments are passed to the start class's static main
            return findStaticMain(args.startClass, args.startArgs, classLoader);
        }
        
    private static Runnable findStaticMain(String className, String[] argv,
                ClassLoader classLoader) {//1
            Class<?> cl;
    
            try {
                cl = Class.forName(className, true, classLoader);
            } catch (ClassNotFoundException ex) {
                throw new RuntimeException(
                        "Missing class when invoking static main " + className,
                        ex);
            }
    
            Method m;
            try {
                m = cl.getMethod("main", new Class[] { String[].class });//2
            } catch (NoSuchMethodException ex) {
                throw new RuntimeException(
                        "Missing static main on " + className, ex);
            } catch (SecurityException ex) {
                throw new RuntimeException(
                        "Problem getting static main on " + className, ex);
            }
    
            int modifiers = m.getModifiers();
            if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
                throw new RuntimeException(
                        "Main method is not public and static on " + className);
            }
    
            /*
             * This throw gets caught in ZygoteInit.main(), which responds
             * by invoking the exception's run() method. This arrangement
             * clears up all the stack frames that were required in setting
             * up the process.
             */
            return new MethodAndArgsCaller(m, argv);//3
        }
    注解1:整个方法都是围绕反射机制来处理
    注解2:绕了一圈,最后这里是执行main方法
    注解3:我们反射最后都市invoke代表执行,这里还没有显示出来,继续分析3
    
    static class MethodAndArgsCaller implements Runnable {
            /** method to call */
            private final Method mMethod;
    
            /** argument array */
            private final String[] mArgs;
    
            public MethodAndArgsCaller(Method method, String[] args) {
                mMethod = method;
                mArgs = args;
            }
    
            public void run() {
                try {
                    mMethod.invoke(null, new Object[] { mArgs });//1
                } catch (IllegalAccessException ex) {
                    throw new RuntimeException(ex);
                } catch (InvocationTargetException ex) {
                    Throwable cause = ex.getCause();
                    if (cause instanceof RuntimeException) {
                        throw (RuntimeException) cause;
                    } else if (cause instanceof Error) {
                        throw (Error) cause;
                    }
                    throw new RuntimeException(ex);
                }
            }
        }
    注解1:反射里面的invoke方法
    
    总结,Zygote进程fork进程的方式就是通过socket把ActivityThread获取到,之后,通过反射执行ActivityThread.main方法。
    这里解释了为什么是ActivityThread而不是其他。
    

    Tips:我们分析anr问题时,其实经常碰见如下log信息:

    system_server进程
    ZygoteInit.main-->RuntimeInit.MethodAndArgsCaller.run-->Method.invoke-->SystemServer.main-->SystemServer.run
    at com.android.server.SystemServer.run(SystemServer.java:446)
    at com.android.server.SystemServer.main(SystemServer.java:280)
    at java.lang.reflect.Method.invoke(Native method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:849)
    
    app进程:
    ZygoteInit.main-->RuntimeInit.MethodAndArgsCaller.run-->Method.invoke-->ActivityThread.main
    at android.app.ActivityThread.main(ActivityThread.java:6523)
    at java.lang.reflect.Method.invoke(Native method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869)
    所以,从log中学习也是一大途径
    

    三、应用进程与AMS通信流程

    ActivityThread.java
    public static void main(String[] args) {
            ······
            Looper.prepareMainLooper();//1
            
            ActivityThread thread = new ActivityThread();
            thread.attach(false);//2
            ······
            Looper.loop();//3
    }
    注解1和注解3:我们在Activity中,一般都是new Handler()即可,从这里可以看到,其实
    Looper的动作仅仅是因为被提前做了而已。
    
    private void attach(boolean system) {
            sCurrentActivityThread = this;
            mSystemThread = system;
            if (!system) {
                ······
                final IActivityManager mgr = ActivityManager.getService();//1
                try {
                    mgr.attachApplication(mAppThread);//2
                } catch (RemoteException ex) {
                    throw ex.rethrowFromSystemServer();
                }
             }
             ······
    }
    注解1:在上面的分析已经有涉及,这里不重复涉及。mgs就是ActivityManagerService对象
    注解2:特别对于mAppThread对象,final ApplicationThread mAppThread = new ApplicationThread();
    (class ApplicationThread extends IApplicationThread.Stub),也就是说,这个类是进行跨进程通信的。
    
    来到AMS:ActivityManagerService.java
    public final void attachApplication(IApplicationThread thread) {
            synchronized (this) {
                int callingPid = Binder.getCallingPid();
                final long origId = Binder.clearCallingIdentity();
                attachApplicationLocked(thread, callingPid);//1
                Binder.restoreCallingIdentity(origId);
            }
    }
    
    private final boolean attachApplicationLocked(IApplicationThread thread,
                int pid) {
            ······
            thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
                            null, null, null, testMode,
                            mBinderTransactionTrackingEnabled, enableTrackAllocation,
                            isRestrictedBackupMode || !normalMode, app.persistent,
                            new Configuration(getGlobalConfiguration()), app.compat,
                            getCommonServicesLocked(app.isolated),
                            mCoreSettingsObserver.getCoreSettingsLocked(),
                            buildSerial);//1
            ······
            // See if the top visible activity is waiting to run in this process...
            if (normalMode) {//2
                try {
                    if (mStackSupervisor.attachApplicationLocked(app)) {//3
                        didSomething = true;
                    }
                } catch (Exception e) {
                    Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
                    badApp = true;
                }
            }
            ······
    }
    注解1:thread就是ActivityThread中的ApplicationThread
    注解2和注解3:如果是Activity,就进行启动Activity:mStackSupervisor.attachApplicationLocked(app)
    
    根据注解1,回到ActivityThread
    public final void bindApplication(······) {
        ······
        sendMessage(H.BIND_APPLICATION, data);
    }
    
    private void handleBindApplication(AppBindData data) {
            ······
            Application app;
            ······
            app = data.info.makeApplication(data.restrictedBackupMode, null);//1
            ······
            InstrumentationInfo ii;
            ······
            if(ii != null) {}
                ······
                mInstrumentation = (Instrumentation)
                        cl.loadClass(data.instrumentationName.getClassName()).newInstance();
                 ······
                 mInstrumentation.init(this, instrContext, appContext, component,
                        data.instrumentationWatcher, data.instrumentationUiAutomationConnection);
             } else {
                mInstrumentation = new Instrumentation();
            }           
            mInstrumentation.onCreate(data.instrumentationArgs);
            mInstrumentation.callApplicationOnCreate(app);//2
            ······ 
    }
    注解1:生成Application对象,同时也调用了attach方法,具体细节如下:
    LoadedApk.makeApplication-->Instrumentation.newApplication,详情我们看Instrumentation:
    static public Application newApplication(Class<?> clazz, Context context)
                throws InstantiationException, IllegalAccessException, 
                ClassNotFoundException {
            Application app = (Application)clazz.newInstance();
            app.attach(context);
            return app;
    }
    注解2:调用Application的生命周期onCreate。
    public void callApplicationOnCreate(Application app) {
            app.onCreate();
    }
    小结,Application执行顺序为attach --> onCreate
    
    上面是App进程没有启动的时候,需要先启动Application。现在我们跟踪一下Application启动好了,会怎么处理?
    分析attachApplicationLocked的注解3:
    ActivityStackSuperviosr.java
    attachApplicationLocked --> realStartActivityLocked
    final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
                boolean andResume, boolean checkConfig) throws RemoteException {
        ······
        app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,//1
                            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, !andResume,
                            mService.isNextTransitionForward(), profilerInfo);
         ······
    }
    注解1:执行ActivityThread中ApplicationThread.scheduleLaunchActivity方法。也就是说,又回到应用进程里面。
    这里,我们补充一下,应用进程--AMS通信时,其实AMS就是在跟ActivityThread.ApplicationThread.schedule***进行回调通信。
    知道了这一点,后面我们就可以先通过ActivityThread找对应的执行方法,了解各个组件的生命周期。
    
    ActivityThread.java
    ApplicationThread.scheduleLaunchActivity --> handleLaunchActivity
    
    private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {
            ······
           Activity a = performLaunchActivity(r, customIntent);//1
    
           if (a != null) {
                r.createdConfig = new Configuration(mConfiguration);
                reportSizeConfigurations(r);
                Bundle oldState = r.state;
                handleResumeActivity(r.token, false, r.isForward,//2
                        !r.activity.mFinished && !r.startsNotResumed, r.lastProcessedSeq, reason);
                ·······
           }
           ······
    }
    先执行注解1,如果a!=null,则执行2
    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
            // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");
    
            ContextImpl appContext = createBaseContextForActivity(r);//1
            Activity activity = null;
            try {
                java.lang.ClassLoader cl = appContext.getClassLoader();
                activity = mInstrumentation.newActivity(//2
                        cl, component.getClassName(), r.intent);
                ······
            } catch (Exception e) {
                
            }
    
            try {
                Application app = r.packageInfo.makeApplication(false, mInstrumentation);
                ······
                if (activity != null) {
                    ······
                    activity.attach(appContext, this, getInstrumentation(), r.token,//3
                            r.ident, app, r.intent, r.activityInfo, title, r.parent,
                            r.embeddedID, r.lastNonConfigurationInstances, config,
                            r.referrer, r.voiceInteractor, window, r.configCallback);
                    ······
                    activity.setTheme(theme);//4
                    ······
                    mInstrumentation.callActivityOnCreate(activity, r.state);//5
                    ······
                    activity.performStart();//6
                    ······
                    mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);//7
                    ······
                    mInstrumentation.callActivityOnPostCreate(activity, r.state);//8
                    ······
                }
                ······            
    }
    注解1和注解3:表明Activity的Context用的实例是ContextImpl
    注解2:初始化了一个Activity对象,具体方法见Instrumentation.newActivity:(Activity)cl.loadClass(className).newInstance().
    看多了系统的代码,你会发现,系统会常用此方法来生成对象。
    注解3:Activity首先调用的方法为attach,这里相当于初始化的地方,例如:PhoneWindow的初始化。从可以看到,Activity的生命周期被调用的时间已经很晚了。
    这里也引出一个问题:getBaseContext和getApplicationContext获取的对象是否一样?
    注解4:设置主题资源
    注解5:真正执行onCreate生命周期的地方。跟踪这段代码,你会发现其实判断条件还很多的,到真正执行onCreate,已经又执行了很多东西了。
    注解6、7、8:生命周期onStart、onRestoreInstanceState、onPostCreate
    总结,通过Instrumentation可全权调用Activity的生命周期
    
    final void handleResumeActivity(IBinder token,
                boolean clearHide, boolean isForward, boolean reallyResume, int seq, String reason) {
                ······
                r = performResumeActivity(token, clearHide, reason);//2
                ······
                if (r.activity.mVisibleFromClient) {
                     r.activity.makeVisible();//3
                }
                ······
    }
    注解2*:执行生命周期onResume。我们详细跟踪一下
    注解3*:让View可以见。也就是说,onResume之后,才是让View可见的时候。
    
    注解2*的详细分析------------start
    ActivityThread.java
    public final ActivityClientRecord performResumeActivity(IBinder token,
                boolean clearHide, String reason) {
            ActivityClientRecord r = mActivities.get(token);
            ······
            r.activity.onStateNotSaved();//1
            ······
            r.activity.performResume();//2
            ······
    }
    注解1:执行生命周期onStateNotSaved
    注解2:执行关键的生命周期onResume。再跟进就是:
    Activity.java
    final void performResume() {
            performRestart();//1
            ······
            mInstrumentation.callActivityOnResume(this);//2
            ······
            onPostResume();//3
    }
    注解1:根据具体情况是否执行生命周期onStart
    注解2:执行生命周期onResume
    注解3:执行生命周期onPostResume
    注解2*的详细分析------------start
    
    注解3*的详细分析------------start
    void makeVisible() {
            if (!mWindowAdded) {
                ViewManager wm = getWindowManager();
                wm.addView(mDecor, getWindow().getAttributes());//1
                mWindowAdded = true;
            }
            mDecor.setVisibility(View.VISIBLE);
        }
    看1处,可知:此时才进行addView操作
    注解3*的详细分析------------end
    

    总结启动Activity的整个过程:

    一、生命周期的流程

    Activity.attach -->Activity.setTheme -->
    
    onCreate -->onStart --> onRestoreInstanceState --> onPostCreate -->
    
    onStateNotSaved --> (onStart) --> onResume -->onPostResume-->(makeVisible)
    

    二、Instrumentation封装了主要生命周期的调用方法

    三、Activity中的PhoneWindow,在执行了onResume之后,才可见

    补充分析差异点:

    getBaseContext和getApplicationContext 可以通过代码分析:

    ContextWrapper.java
    public Context getBaseContext() {
            return mBase;
        }
    

    getBaseContext:源于ContextWrapper类,对象为Context。不管是Application还是Activity,都有mBase

    ContextImpl.java
    public Context getApplicationContext() {
            return (mPackageInfo != null) ?
                    mPackageInfo.getApplication() : mMainThread.getApplication();
    }
    

    getApplicationContext:源于Context类,对象为Application,每个应用都有唯一的一个Application对象

    四、整体总结

    应用进程启动流程.png

    Tips:
    Instrumentation.java承载了Application和Activity的生命周期的执行,所以,是不是可以hook它做很多事情了?

    相关文章

      网友评论

        本文标题:Android 系统分析进程及Activity启动分析

        本文链接:https://www.haomeiwen.com/subject/uhlfictx.html