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

提问:

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 IActivityManagerSingleton =
            new Singleton() {
                @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 {
    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 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 fds = new ArrayList();
        ArrayList peers = new ArrayList();

        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启动分析)