提问:
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的关系,我们用一张图表示:
我们结合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对象
四、整体总结
Tips:
Instrumentation.java承载了Application和Activity的生命周期的执行,所以,是不是可以hook它做很多事情了?