还回到上一篇结束的地方:
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) { 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); 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);
}进程存在情况下启动app
看realStartActivityLocked方法
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
boolean andResume, boolean checkConfig) throws RemoteException { ...
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
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); ...
return true;
}这个地方调用了一个app.thread.scheduleLaunchActivity,这里其实调用的是ActivityThread的子类ApplicationThread里面的scheduleLaunchActivity方法
// we use token to identify this activity without having to send the// activity itself back to the activity manager. (matters more with ipc)@Overridepublic final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
ActivityInfo info, Configuration curConfig, Configuration overrideConfig,
CompatibilityInfo compatInfo, String referrer, IVoiceInteractor voiceInteractor, int procState, Bundle state, PersistableBundle persistentState,
List<ResultInfo> pendingResults, List<ReferrerIntent> pendingNewIntents, boolean notResumed, boolean isForward, ProfilerInfo profilerInfo) {
updateProcessState(procState, false);
ActivityClientRecord r = new ActivityClientRecord();
r.token = token;
r.ident = ident;
r.intent = intent;
r.referrer = referrer;
r.voiceInteractor = voiceInteractor;
r.activityInfo = info;
r.compatInfo = compatInfo;
r.state = state;
r.persistentState = persistentState;
r.pendingResults = pendingResults;
r.pendingIntents = pendingNewIntents;
r.startsNotResumed = notResumed;
r.isForward = isForward;
r.profilerInfo = profilerInfo;
r.overrideConfig = overrideConfig;
updatePendingConfiguration(curConfig);
sendMessage(H.LAUNCH_ACTIVITY, r);
}//下面就到了你最熟悉的Handler通信去启动Activity//--->private 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.sendMessage(msg);
}
...public void handleMessage(Message msg) { if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what)); switch (msg.what) { case LAUNCH_ACTIVITY: {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart"); final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
r.packageInfo = getPackageInfoNoCheck(
r.activityInfo.applicationInfo, r.compatInfo);
handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
} break;
...private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) { ...
// Initialize before creating the activity
WindowManagerGlobal.initialize();
//执行启动Activity
Activity a = performLaunchActivity(r, customIntent); ...}这个方法里面你会看到各种关于一个Activity的重要的方法,例如:activity.attach跟当前ActivityThread绑定,activity.setTheme设置主题等等,到这里基本上到Activity的范畴了,下面我们去看另一种情况,新建进程的情况。
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
// System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");
...
Activity activity = null;
try {
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
if (localLOGV) Slog.v(
TAG, r + ": app=" + app
+ ", appName=" + app.getPackageName()
+ ", pkg=" + r.packageInfo.getPackageName()
+ ", comp=" + r.intent.getComponent().toShortString()
+ ", dir=" + r.packageInfo.getAppDir());
if (activity != null) {
CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
Configuration config = new Configuration(mCompatConfiguration);
if (r.overrideConfig != null) {
config.updateFrom(r.overrideConfig);
}
if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
+ r.activityInfo.name + " with config " + config);
Window window = null;
if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {
window = r.mPendingRemoveWindow;
r.mPendingRemoveWindow = null;
r.mPendingRemoveWindowManager = null;
}
appContext.setOuterContext(activity);
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);
if (customIntent != null) {
activity.mIntent = customIntent;
}
r.lastNonConfigurationInstances = null;
checkAndBlockForNetworkAccess();
activity.mStartedActivity = false;
int theme = r.activityInfo.getThemeResource();
if (theme != 0) {
activity.setTheme(theme);
}
activity.mCalled = false;
if (r.isPersistable()) {
mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
} else {
mInstrumentation.callActivityOnCreate(activity, r.state);
}
if (!activity.mCalled) {
throw new SuperNotCalledException( "Activity " + r.intent.getComponent().toShortString() + " did not call through to super.onCreate()");
}
r.activity = activity;
r.stopped = true;
if (!r.activity.mFinished) {
activity.performStart();
r.stopped = false;
}
if (!r.activity.mFinished) {
if (r.isPersistable()) {
if (r.state != null || r.persistentState != null) {
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state,
r.persistentState);
}
} else if (r.state != null) {
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
}
}
if (!r.activity.mFinished) {
activity.mCalled = false;
if (r.isPersistable()) {
mInstrumentation.callActivityOnPostCreate(activity, r.state,
r.persistentState);
} else {
mInstrumentation.callActivityOnPostCreate(activity, r.state);
}
if (!activity.mCalled) {
throw new SuperNotCalledException( "Activity " + r.intent.getComponent().toShortString() + " did not call through to super.onPostCreate()");
}
}
}
r.paused = true;
mActivities.put(r.token, r);
} catch (SuperNotCalledException e) {
throw e;
} catch (Exception e) {
if (!mInstrumentation.onException(activity, e)) {
throw new RuntimeException( "Unable to start activity " + component
+ ": " + e.toString(), e);
}
}
return activity;}新建进程启动app
0xa
看mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
“activity”, r.intent.getComponent(), false, false, true);
这里又要回到ActivityManagerService这个类中去,这里有个地方需要注意,在startProcessLocked方法里面又调用了一个startProcessLocked方法,参数不一样,加入一个需要注意的参数叫做entryPoint,并且参数为null
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) { long startTime = SystemClock.elapsedRealtime();
ProcessRecord app;
...
checkTime(startTime, "startProcess: stepping in to startProcess");
startProcessLocked(
app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
checkTime(startTime, "startProcess: done starting proc!"); return (app.pid != 0) ? app : null;
}0xb
又调用了 void startProcessLocked(ProcessRecord app, String hostingType,
String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs)
//startProcessLocked方法...//这里由上面0xa处传递的空的entryPoint,到这里赋值给"android.app.ActivityThread" //后面要用到这个,通过反射来调用main方法 boolean isActivityProcess = (entryPoint == null);if (entryPoint == null) entryPoint = "android.app.ActivityThread";...startResult = Process.start(entryPoint, app.processName, uid, uid, gids, debugFlags, mountExternal, app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet, app.info.dataDir, invokeWith, entryPointArgs);...
Process.java
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 invokeWith, String[] zygoteArgs) {
return zygoteProcess.start(processClass, niceName, uid, gid, gids,
debugFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, invokeWith, zygoteArgs);
}每一个app进程都是由Zygote进程fork自身得来的,包括SystemServer进程都是由Zygote fork出来的,下面去看看zygoteProcess的代码,网上分析应用启动流程的结论是app入口是在AcitivtyThread的main方法。那么这个main方法在哪个地方调用,离这里还有多远呢?
ZygoteProcess.java
public final Process.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 invokeWith,
String[] zygoteArgs) { try { return startViaZygote(processClass, niceName, uid, gid, gids,
debugFlags, mountExternal, targetSdkVersion, seInfo,
abi, instructionSet, appDataDir, invokeWith, zygoteArgs);
} catch (ZygoteStartFailedEx ex) {
Log.e(LOG_TAG, "Starting VM process through Zygote failed"); throw new RuntimeException( "Starting VM process through Zygote failed", ex);
}
}/**
* Starts a new process via the zygote mechanism.
* 通过zygote机制开启一个进程
*/private Process.ProcessStartResult startViaZygote(final String processClass,.....)throws ZygoteStartFailedEx {
... synchronized(mLock) { return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);
}
}/**
* 把参数列表传递给zygote进程,zygote进程返回新进程的pid
* @throws ZygoteStartFailedEx if process start failed for any reason
*/@GuardedBy("mLock")private static Process.ProcessStartResult zygoteSendArgsAndGetResult(
ZygoteState zygoteState, ArrayList<String> args) throws ZygoteStartFailedEx { try {
... 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(); //新建进程启动结果类,把新建的结果例如进程pid等赋值给这个结果类,用来返回
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;
} catch (IOException ex) {
zygoteState.close(); throw new ZygoteStartFailedEx(ex);
}
}现在拿到了ProcessStartResult,其实这个时候新进程已经被启动了,那么在哪个地方启动的呢?看一下这个方法zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);需要传入一个ZygoteState,这个是ZygoteProcess的一个内部类,包含着与zygote进程的连接状态,一共有两个
/** * The state of the connection to the primary zygote. */private ZygoteState primaryZygoteState;/** * The state of the connection to the secondary zygote. */private ZygoteState secondaryZygoteState;
看一下openZygoteSocketIfNeeded方法,尝试与Zygote进程建立socket连接,socket也是一种通信方式,primaryZygoteState为空或者关闭之后,尝试去建立连接,这个ZygoteState匹配直接返回使用,不匹配继续去使用secondaryZygoteState连接,两个都不匹配或者为空,没连接上等等抛异常。总之这里需要一个可以使用的socket连接。拿到这个ZygoteState连接状态后就可以去写操作,而与之建立连接的Zygote进程会读取到这个信息,那么在哪个里读取的呢?继续往下看。
/**
* Tries to open socket to Zygote process if not already open. If
* already open, does nothing. May block and retry. Requires that mLock be held.
*/@GuardedBy("mLock")private ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx {
Preconditions.checkState(Thread.holdsLock(mLock), "ZygoteProcess lock not held"); if (primaryZygoteState == null || primaryZygoteState.isClosed()) { try {
primaryZygoteState = ZygoteState.connect(mSocket);
} catch (IOException ioe) { throw new ZygoteStartFailedEx("Error connecting to primary zygote", ioe);
}
} if (primaryZygoteState.matches(abi)) { return primaryZygoteState;
} // The primary zygote didn't match. Try the secondary.
if (secondaryZygoteState == null || secondaryZygoteState.isClosed()) { try {
secondaryZygoteState = ZygoteState.connect(mSecondarySocket);
} catch (IOException ioe) { throw new ZygoteStartFailedEx("Error connecting to secondary zygote", ioe);
}
} if (secondaryZygoteState.matches(abi)) { return secondaryZygoteState;
} throw new ZygoteStartFailedEx("Unsupported zygote ABI: " + abi);
}zygote在启动之后开启了socket 监听功能,监听需要创建 Process 的请求,关于zygote进程什么时候开启这个socket的需要去看zygote的启动流程。这里我们关心的主要有三个类:
ZygoteInit.java
ZygoteServer.java
ZygoteConnection.java
摘自:https://blog.csdn.net/luoshengyang/article/details/6768304
我们知道,Android系统是基于Linux内核的,而在Linux系统中,所有的进程都是init进程的子孙进程,也就是说,所有的进程都是直接或者间接地由init进程fork出来的。Zygote进程也不例外,它是在系统启动的过程,由init进程创建的。在系统启动脚本system/core/rootdir/init.rc文件中
Zygote进程启动的时候会调用ZygoteInit的main方法,关于Zygote启动流程我不想多说,感兴趣可以去看一下他的源码,这里我们看到zygoteServer.runSelectLoop(abiList);注释说的是接受socket连接
ZygoteInit.java
public static void main(String argv[]) {
ZygoteServer zygoteServer = new ZygoteServer(); // Mark zygote start. This ensures that thread creation will throw
// an error.
ZygoteHooks.startZygoteNoThreadCreation(); // Zygote goes into its own process group.
try {
Os.setpgid(0, 0);
} catch (ErrnoException ex) { throw new RuntimeException("Failed to setpgid(0,0)", ex);
} try {
...
Log.i(TAG, "Accepting command socket connections");
zygoteServer.runSelectLoop(abiList);
zygoteServer.closeServerSocket();
} catch (Zygote.MethodAndArgsCaller caller) {
caller.run();
} catch (Throwable ex) {
Log.e(TAG, "System zygote died with exception", ex);
zygoteServer.closeServerSocket(); throw ex;
}
}ZygoteServer.java
/**
* Runs the zygote process's select loop. Accepts new connections as
* they happen, and reads commands from connections one spawn-request's
* worth at a time.
*
* @throws Zygote.MethodAndArgsCaller in a child process when a main()
* should be executed.
*/void runSelectLoop(String abiList) throws Zygote.MethodAndArgsCaller {
ArrayList<FileDescriptor> fds = new ArrayList<FileDescriptor>();
ArrayList<ZygoteConnection> peers = new ArrayList<ZygoteConnection>();
fds.add(mServerSocket.getFileDescriptor());
peers.add(null); while (true) {
StructPollfd[] pollFds = new StructPollfd[fds.size()]; for (int i = 0; i < pollFds.length; ++i) {
pollFds[i] = new StructPollfd();
pollFds[i].fd = fds.get(i);
pollFds[i].events = (short) POLLIN;
} try {
Os.poll(pollFds, -1);
} catch (ErrnoException ex) { throw new RuntimeException("poll failed", ex);
} for (int i = pollFds.length - 1; i >= 0; --i) { if ((pollFds[i].revents & POLLIN) == 0) { continue;
} if (i == 0) {
ZygoteConnection newPeer = acceptCommandPeer(abiList);
peers.add(newPeer);
fds.add(newPeer.getFileDesciptor());
} else { boolean done = peers.get(i).runOnce(this); if (done) {
peers.remove(i);
fds.remove(i);
}
}
}
}
}下面看看ZygoteConnection类,从socket读取信息,成功的话表示一个子进程被成功fork,失败抛异常。当有新进程连接请求时,唤醒Zygote进程,执行ZygoteConnection的runOnce这个方法。
/**
* Reads one start command from the command socket. If successful,
* a child is forked and a {@link Zygote.MethodAndArgsCaller}
* exception is thrown in that child while in the parent process,
* the method returns normally. On failure, the child is not
* spawned and messages are printed to the log and stderr. Returns
* a boolean status value indicating whether an end-of-file on the command
* socket has been encountered.
*
* @return false if command socket should continue to be read from, or
* true if an end-of-file has been encountered.
* @throws Zygote.MethodAndArgsCaller trampoline to invoke main()
* method in child process
*/
boolean runOnce(ZygoteServer zygoteServer) throws Zygote.MethodAndArgsCaller {
String args[];
Arguments parsedArgs = null;
FileDescriptor[] descriptors; try { //这里的readArgumentList()就是去获取刚才ZygoteProgress类的BufferedWriter writer = zygoteState.writer //写入的writer.write(arg);这些参数 //
args = readArgumentList();
descriptors = mSocket.getAncillaryFileDescriptors();
} catch (IOException ex) {
Log.w(TAG, "IOException on command socket " + ex.getMessage());
closeSocket(); return true;
}
...
int pid = -1;
FileDescriptor childPipeFd = null;
FileDescriptor serverPipeFd = null; try {
... //获取到被fork出来的新进程的pid
pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
parsedArgs.niceName, fdsToClose, fdsToIgnore, parsedArgs.instructionSet,
parsedArgs.appDataDir);
} catch (ErrnoException ex) {
logAndPrintError(newStderr, "Exception creating pipe", ex);
} catch (IllegalArgumentException ex) {
logAndPrintError(newStderr, "Invalid zygote arguments", ex);
} catch (ZygoteSecurityException ex) {
logAndPrintError(newStderr, "Zygote security policy prevents request: ", ex);
} try { if (pid == 0) { // 返回的pid为0表示在孵化出来的子进程里面,也就是应用进程里面
zygoteServer.closeServerSocket();
IoUtils.closeQuietly(serverPipeFd);
serverPipeFd = null;
handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr); // should never get here, the child is expected to either // throw Zygote.MethodAndArgsCaller or exec(). return true;
} else { // in parent...pid of < 0 means failure
IoUtils.closeQuietly(childPipeFd);
childPipeFd = null; return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs);
}
} finally {
IoUtils.closeQuietly(childPipeFd);
IoUtils.closeQuietly(serverPipeFd);
}
}继续追踪Zygote.forkAndSpecialize发现最后到了Zygote类的nativeForkAndSpecialize方法,到这调用的就是底层c/c++代码了。这里有一点需要注意:Android也属于Linux系统,所以Android的Zygote进程的fork过程也是Linux系统中的进程fork过程,由于对Linux的进程fork不是太了解,我在这里只能直接说结论,那就是执行完pid = Zygote.forkAndSpecialize这个方法,这里其实就变成了两个进程,也就是一次执行两次返回,两次返回是在两个进程中进行的。一个是在子进程也就是应用进程,一个是原来的Zygote的进程,也就是这里pid = Zygote.forkAndSpecialize往下执行,会执行两次,一次是子进程中,这时候pid=0,表示子进程创建成功;一次是Zygote进程中,pid不为0,不为0的情况还有可能是在异常的情况,但是种异常的情况就先不考虑了。
关于cpp文件的分析,参考这里https://www.2cto.com/kf/201607/527963.html
nativeForkAndSpecialize()方法最终调用的是com_android_internal_os_Zygote.cpp中的 com_android_internal_os_Zygote_nativeForkAndSpecialize()方法,链接在这里https://android.googlesource.com/platform/frameworks/base/+/android-cts-8.0_r8/core/jni/com_android_internal_os_Zygote.cpp
native private static int nativeForkAndSpecialize(int uid, int gid, int[] gids,int debugFlags, int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose, int[] fdsToIgnore, String instructionSet, String appDataDir);
com_android_internal_os_Zygote.cpp文件
static jint com_android_internal_os_Zygote_nativeForkAndSpecialize(
JNIEnv* env, jclass, jint uid, jint gid, jintArray gids,
jint debug_flags, jobjectArray rlimits,
jint mount_external, jstring se_info, jstring se_name,
jintArray fdsToClose,
jintArray fdsToIgnore,
jstring instructionSet, jstring appDataDir) { ...
return ForkAndSpecializeCommon(env, uid, gid, gids, debug_flags,
rlimits, capabilities, capabilities, mount_external, se_info,
se_name, false, fdsToClose, fdsToIgnore, instructionSet, appDataDir);
}关于进程的fork过程都是jni的cpp文件,这里不再继续深入,感兴趣可以去看看上面的那个链接分析的更多一些。下面继续考虑上面两个进程的返回,都是怎么走的,先考虑在Zygote进程也就是pid不为0情况,可以看到handleParentProc方法就是通过socket把pid返回回去。
//处理Zygote进程后续工作
private boolean handleParentProc(int pid,
FileDescriptor[] descriptors, FileDescriptor pipeFd, Arguments parsedArgs) { ...
try {
mSocketOutStream.writeInt(pid);
mSocketOutStream.writeBoolean(usingWrapper);
} catch (IOException ex) {
Log.e(TAG, "Error writing to command socket", ex); return true;
} return false;
}然后看看子进程中做了哪些处理,进入handleChildProc方法,parsedArgs.invokeWith != null执行WrapperInit.execApplication,这个我们要去看看invokeWith传过来的是什么
//处理子进程的设置初始化工作private void handleChildProc(Arguments parsedArgs,
FileDescriptor[] descriptors, FileDescriptor pipeFd, PrintStream newStderr) throws Zygote.MethodAndArgsCaller { /**
* By the time we get here, the native code has closed the two actual Zygote
* socket connections, and substituted /dev/null in their place. The LocalSocket
* objects still need to be closed properly.
*/
closeSocket(); if (descriptors != null) { try {
Os.dup2(descriptors[0], STDIN_FILENO);
Os.dup2(descriptors[1], STDOUT_FILENO);
Os.dup2(descriptors[2], STDERR_FILENO); for (FileDescriptor fd: descriptors) {
IoUtils.closeQuietly(fd);
}
newStderr = System.err;
} catch (ErrnoException ex) {
Log.e(TAG, "Error reopening stdio", ex);
}
} if (parsedArgs.niceName != null) {
Process.setArgV0(parsedArgs.niceName);
} // End of the postFork event.
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); if (parsedArgs.invokeWith != null) {
WrapperInit.execApplication(parsedArgs.invokeWith,
parsedArgs.niceName, parsedArgs.targetSdkVersion,
VMRuntime.getCurrentInstructionSet(),
pipeFd, parsedArgs.remainingArgs);
} else {
ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion,
parsedArgs.remainingArgs, null /* classLoader */);
}
}在ActivityManagerService的startProcessLocked方法里面,这个invokeWith默认为null,这个应该是Debuggable apps时才会用到的,所以直接考虑ZygoteInit.zygoteInit的情况
String invokeWith = null;if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { // Debuggable apps may include a wrapper script with their library directory.
String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh";
StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); try { if (new File(wrapperFileName).exists()) {
invokeWith = "/system/bin/logwrapper " + wrapperFileName;
}
} finally {
StrictMode.setThreadPolicy(oldPolicy);
}
}ZygoteInit.java文件
public static final void zygoteInit(int targetSdkVersion, String[] argv,
ClassLoader classLoader) throws Zygote.MethodAndArgsCaller {
if (RuntimeInit.DEBUG) {
Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");
}
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");
RuntimeInit.redirectLogStreams();
RuntimeInit.commonInit();
ZygoteInit.nativeZygoteInit();
RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
}ZygoteInit.nativeZygoteInit();里面有时c++代码,就是执行进程初始化工作,先不去看了,看看RuntimeInit.applicationInit方法
protected static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
throws Zygote.MethodAndArgsCaller { ...
// Remaining arguments are passed to the start class's static main
invokeStaticMain(args.startClass, args.startArgs, classLoader);
}/**
* Invokes a static "main(argv[]) method on class "className".
* Converts various failing exceptions into RuntimeExceptions, with
* 根据className去调用它的main方法,那么这个main方法是哪个呢?
* 其实就是ActivityThead的main方法,我们可以去看看上面
* 0xa和0xb处的描述,是不传递了这个参数过来
* @param className Fully-qualified class name
* @param argv Argument vector for main()
* @param classLoader the classLoader to load {@className} with
*/private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader) throws Zygote.MethodAndArgsCaller {
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 });
} 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.
*/
throw new Zygote.MethodAndArgsCaller(m, argv); //使用MethodAndArgsCaller对象抛异常,然后在这个异常里面执行是个main方法}public static class MethodAndArgsCaller extends Exception
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 });
} 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);
}
}
}到此位置我们早到了ActivityThread main方法启动的地方,这个main方法中做了很多app的初始化工作,其中就包括著名的Looper.prepareMainLooper();以及Looper.loop(); 然后后面的事就交给Activity范畴的handler处理了。
ActivityThread.java
public static void main(String[] args) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
SamplingProfilerIntegration.start(); // CloseGuard defaults to true and can be quite spammy. We
// disable it here, but selectively enable it later (via
// StrictMode) on debug builds, but using DropBox, not logs.
CloseGuard.setEnabled(false);
Environment.initForCurrentUser(); // Set the reporter for event logging in libcore
EventLogger.setReporter(new EventLoggingReporter()); // Make sure TrustedCertificateStore looks in the right place for CA certificates
final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
TrustedCertificateStore.setDefaultUserDirectory(configDir);
Process.setArgV0("<pre-initialized>");
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false); if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler();
} if (false) {
Looper.myLooper().setMessageLogging(new
LogPrinter(Log.DEBUG, "ActivityThread"));
} // End of event ActivityThreadMain.
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited");
}参考连接
关于参考连接实在是太多了,也许没有列举完,还请谅解
https://blog.csdn.net/luoshengyang/article/details/6747696
https://www.2cto.com/kf/201607/527963.html
https://blog.csdn.net/tfygg/article/details/53563638
http://www.cloudchou.com/android/post-805.html
https://juejin.im/entry/576e42f9128fe1005a27fc11
http://mouxuejie.com/blog/2016-03-12/activity-launch-analysis/
随时随地看视频