Android(安卓)四大组件 - 进程的 fork 创建过程
相关文章链接:
1. Android Framework - 学习启动篇
2. Android 系统服务 - AMS 的启动过程
3. Android 系统服务 - PMS 的启动过程
4. Android Framework - 开机启动 Zygote 进程
相关源码文件:
/frameworks/base/services/core/java/android/os/Process.java/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java/frameworks/base/core/java/com/android/internal/os/ZygoteConnection.java/frameworks/base/core/java/com/android/internal/os/Zygote.java/frameworks/base/core/jni/com_android_internal_os_Zygote.cpp/frameworks/base/core/java/android/app/ActivityThread.java/frameworks/base/core/java/android/app/LoadedApk.java
1. AMS 与 Zygote 通信过程
无论是点击桌面图标调用 startActivitySafely 还是直接调用 startActivity 在源码中都是调用的 startActivityForResult 方法。由于 Activity 的启动流程有些复杂,因此本文先从进程的 fork 创建过程来入手分析。
void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) { // Is this activity's process already running? ProcessRecord app = mService.getProcessRecordLocked(r.processName, r.info.applicationInfo.uid, true); r.task.stack.setLaunchTime(r); // 判断进程是否创建 if (app != null && app.thread != null) { ... } // 当前进程没有创建则先创建进程 mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0, "activity", r.intent.getComponent(), false, false, true); } private final void startProcessLocked(ProcessRecord app, String hostingType, String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { try { // 设置参数 ... // 设置 entryPoint = "android.app.ActivityThread" boolean isActivityProcess = (entryPoint == null); if (entryPoint == null) entryPoint = "android.app.ActivityThread"; // 启动创建进程 Process.ProcessStartResult startResult = Process.start(entryPoint, app.processName, uid, uid, gids, debugFlags, mountExternal, app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, app.info.dataDir, entryPointArgs); synchronized (mPidsSelfLocked) { // 缓存 pid 和 进程信息 this.mPidsSelfLocked.put(startResult.pid, app); ... } ... } catch (RuntimeException e) { ... } } private static ProcessStartResult startViaZygote(final String processClass, final String niceName, final int uid, final int gid, final int[] gids, int debugFlags, int mountExternal, int targetSdkVersion, String seInfo, String abi, String instructionSet, String appDataDir, String[] extraArgs) throws ZygoteStartFailedEx { synchronized(Process.class) { ArrayList argsForZygote = new ArrayList(); // 添加创建进程的基本参数 argsForZygote.add("--runtime-args"); argsForZygote.add("--setuid=" + uid); argsForZygote.add("--setgid=" + gid); ... argsForZygote.add("--target-sdk-version=" + targetSdkVersion); ... // 向 zygote 发起创建进程的请求,通过 socket 的方式 return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote); } } // 打开 zygot socket 连接 private static ZygoteState openZygoteSocketIfNeeded(String abi) throws ZygoteStartFailedEx { if (primaryZygoteState == null || primaryZygoteState.isClosed()) { try { primaryZygoteState = ZygoteState.connect(ZYGOTE_SOCKET); } 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(SECONDARY_ZYGOTE_SOCKET); } 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); } private static ProcessStartResult zygoteSendArgsAndGetResult( ZygoteState zygoteState, ArrayList args) throws ZygoteStartFailedEx { try { // 获取 socket 的 output 与 input final BufferedWriter writer = zygoteState.writer; final DataInputStream inputStream = zygoteState.inputStream; // 把数据传送给 zygote 进程 writer.write(Integer.toString(args.size())); writer.newLine(); int sz = args.size(); for (int i = 0; i < sz; i++) { String arg = args.get(i); if (arg.indexOf('\n') >= 0) { throw new ZygoteStartFailedEx( "embedded newlines not allowed"); } writer.write(arg); writer.newLine(); } writer.flush(); // 处理 zygote fork 进程返回的结果 ProcessStartResult result = new ProcessStartResult(); result.pid = inputStream.readInt(); if (result.pid < 0) { throw new ZygoteStartFailedEx("fork() failed"); } result.usingWrapper = inputStream.readBoolean(); return result; } catch (IOException ex) { // 有异常则关闭连接 zygoteState.close(); throw new ZygoteStartFailedEx(ex); } }
activity 的启动过程中会掉用 startSpecificActivityLocked 方法,首先会根据 processName 和 uid 来判断进程是否有创建,如果没有创建进程则需要先创建进程,processName 默认情况是包名,uid 是由 PMS 在启动的过程中解析计算好的,其具体的计算赋值过程可以参考《Android 系统服务 - PMS 的启动过程》
如果当前进程没有创建,则调用 Process 的 startViaZygote 方法去创建进程,就是向 Zygote 进程发起创建进程的请求,这里跨进程通信采用的是 Socket 套接字的方式。注意,其中有一个重要的参数 entryPoint 是 android.app.ActivityThread 。
2. Zygote fork 创建进程
// 循环读取处理请求 private static void runSelectLoop(String abiList) throws MethodAndArgsCaller { ArrayList fds = new ArrayList(); ArrayList peers = new ArrayList(); fds.add(sServerSocket.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(); if (done) { peers.remove(i); fds.remove(i); } } } } } boolean runOnce() throws ZygoteInit.MethodAndArgsCaller { try { // 读取 AMS 发过来的参数 args = readArgumentList(); } catch (IOException ex) { ... return true; } try { parsedArgs = new Arguments(args); // fork 创建进程 pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids, parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo, parsedArgs.niceName, fdsToClose, parsedArgs.instructionSet, parsedArgs.appDataDir); } catch (ErrnoException ex) { ... } try { if (pid == 0) { // child process 处理 handleChildProc(parsedArgs, descriptors, childPipeFd, newStderr); return true; } else { // parent process 处理 return handleParentProc(pid, descriptors, serverPipeFd, parsedArgs); } } finally { IoUtils.closeQuietly(childPipeFd); IoUtils.closeQuietly(serverPipeFd); } } public static int forkAndSpecialize(int uid, int gid, int[] gids, int debugFlags, int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose, String instructionSet, String appDataDir) { int pid = nativeForkAndSpecialize( uid, gid, gids, debugFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose, instructionSet, appDataDir); ... return pid; } static pid_t ForkAndSpecializeCommon(JNIEnv* env, uid_t uid, gid_t gid, jintArray javaGids, jint debug_flags, jobjectArray javaRlimits, jlong permittedCapabilities, jlong effectiveCapabilities, jint mount_external, jstring java_se_info, jstring java_se_name, bool is_system_server, jintArray fdsToClose, jstring instructionSet, jstring dataDir) { // 调用系统函数 fork pid_t pid = fork(); ... return pid; } private void handleChildProc(Arguments parsedArgs, FileDescriptor[] descriptors, FileDescriptor pipeFd, PrintStream newStderr) throws ZygoteInit.MethodAndArgsCaller { // 关闭 zygote 进程继承过来的 socket 连接 closeSocket(); ZygoteInit.closeServerSocket(); ... if (parsedArgs.invokeWith != null) { ... } else { RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, null /* classLoader */); } } public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) throws ZygoteInit.MethodAndArgsCaller { // common 初始化 commonInit(); // 初始化打开 binder 驱动 nativeZygoteInit(); // 抛异常,然后执行 ActivityThread.main 方法 applicationInit(targetSdkVersion, argv, classLoader); }
Zygote 启动后会循环处理客户端发过来的请求,当接收到请求后会调用 ZygoteConnection 的 runOnce 方法,解析到客户端的参数后会调用 native 底层的 fork 的方法,至此进程才真正创建完毕。进程 fork 完毕后,Zygote 进程会将信息返回给 AMS,新创建的进程会调用 commonInit 、nativeZygoteInit 和 applicationInit 三个核心方法:
- commonInit:通用初始化方法
- nativeZygoteInit:打开底层 binder 驱动
- applicationInit:调用 ActivityThread 的 main 方法
3. Application 的创建与绑定
public static void main(String[] args) { // 创建主线程 Looper Looper.prepareMainLooper(); ActivityThread thread = new ActivityThread(); thread.attach(false); // 进入 loop 循环 Looper.loop(); } private void attach(boolean system) { if (!system) { final IActivityManager mgr = ActivityManagerNative.getDefault(); try { // 像 AMS 发起绑定请求 mgr.attachApplication(mAppThread); } catch (RemoteException ex) { // Ignore } ... } else { ... } } public final void attachApplication(IApplicationThread thread) { synchronized (this) { int callingPid = Binder.getCallingPid(); final long origId = Binder.clearCallingIdentity(); attachApplicationLocked(thread, callingPid); Binder.restoreCallingIdentity(origId); } } private final boolean attachApplicationLocked(IApplicationThread thread, int pid) { // 通过 pid 查询到进程信息,之前 fork 后有缓存 ProcessRecord app; if (pid != MY_PID && pid >= 0) { synchronized (mPidsSelfLocked) { app = mPidsSelfLocked.get(pid); } } else { app = null; } ... // 绑定 thread app.makeActive(thread, mProcessStats); ... try { // 回调 bindApplication 方法 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass, profilerInfo, app.instrumentationArguments, app.instrumentationWatcher, app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent, new Configuration(mConfiguration), app.compat, getCommonServicesLocked(app.isolated), mCoreSettingsObserver.getCoreSettingsLocked()); } catch (Exception e) { ... return false; } return true; } private void handleBindApplication(AppBindData data) { try { // 创建绑定 Application Application app = data.info.makeApplication(data.restrictedBackupMode, null); mInitialApplication = app; } finally { StrictMode.setThreadPolicy(savedPolicy); } } public Application makeApplication(boolean forceDefaultAppClass, Instrumentation instrumentation) { if (mApplication != null) { return mApplication; } Application app = null; // 查找到 application 的 class String appClass = mApplicationInfo.className; if (forceDefaultAppClass || (appClass == null)) { // 默认是 android.app.Application appClass = "android.app.Application"; } try { // 先创建 ClassLoader java.lang.ClassLoader cl = getClassLoader(); if (!mPackageName.equals("android")) { initializeJavaContextClassLoader(); } // 创建一个 ContextImpl ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this); // 创建和绑定 Application app = mActivityThread.mInstrumentation.newApplication( cl, appClass, appContext); appContext.setOuterContext(app); } catch (Exception e) { if (!mActivityThread.mInstrumentation.onException(app, e)) { throw new RuntimeException( "Unable to instantiate application " + appClass + ": " + e.toString(), e); } } mActivityThread.mAllApplications.add(app); mApplication = app; if (instrumentation != null) { try { // 调用 Application 的 onCreate 方法 instrumentation.callApplicationOnCreate(app); } catch (Exception e) { if (!instrumentation.onException(app, e)) { throw new RuntimeException( "Unable to create application " + app.getClass().getName() + ": " + e.toString(), e); } } } ... return app; } // 创建 application 并且调用 attach 方法 static public Application newApplication(Class<?> clazz, Context context) throws InstantiationException, IllegalAccessException, ClassNotFoundException { Application app = (Application)clazz.newInstance(); app.attach(context); return app; }
进程 fork 后会执行 ActivityThread 的 main 方法,该方法又会向 AMS 发起绑定 IApplicationThread 请求,这里 IApplicationThread 是一个可以跨进程通信的 Binder 对象,然后 AMS 又会调用 IApplicationThread 的 bindApplication 方法去创建应用的 Application,等应用的 Application 创建完毕后,才会真正的开始创建启动 Activity 。
视频地址:https://pan.baidu.com/s/1tB9hDc_6Aw_L0pgtbAU8Sw
视频密码:6fzw
更多相关文章
- 一款霸榜 GitHub 的开源 Linux 资源监视器!
- 关于如何获取android状态栏高度
- Android(安卓)Okhttp + Android提交post表单乱码问题
- Android(安卓)Toast cancel问题、源码分析和解决方案
- Android系统启动分析(Init->Zygote->SystemServer->Home activit
- [Android(安卓)相机]Android(安卓)相机开发的基本流程
- Android(安卓)知识点积累(一)
- android判断是否联网
- Java/Android(安卓)Annotation processor实践:greendaoannotation