一. 概述Android系统将进程做得很友好的封装,对于上层app开发者来说进程几乎是透明的. 了解Android的朋友,一定知道Android四大组件,但对于进程可能会相对较陌生. 一个进程里面可以跑多个app(通过share uid的方式), 一个app也可以跑在多个进程里(通过配置Android:process属性). 再进一步进程是如何创建的, 可能很多人不知道fork的存在. 在我的文章 理解Android进程创建流程 集中一点详细介绍了 二. 四大组件与进程2.1 startProcessLocked在 //方法 1(a) final ProcessRecord startProcessLocked( String processName, ApplicationInfo info, boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, boolean allowWhileBooting, boolean isolated, boolean keepIfLarge) //方法 1(b) 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) //方法 2(a) private final void startProcessLocked( ProcessRecord app, String hostingType, String hostingNameStr) //方法 2(b) private final void startProcessLocked( ProcessRecord app, String hostingType, String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) 1(a) ==> 1(b):方法1(a)将isolatedUid=0,其他参数赋值为null,再调用给1(b) 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 */); } 2(a) ==> 2(b):方法2(a)将其他3个参数abiOverride,entryPoint, entryPointArgs赋值为null,再调用给2(b) private final void startProcessLocked(ProcessRecord app, String hostingType, String hostingNameStr) { startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */, null /* entryPoint */, null /* entryPointArgs */); } 小结:
2.2 四大组件与进程Activity, Service, ContentProvider, BroadcastReceiver这四大组件,在启动的过程,当其所承载的进程不存在时需要先创建进程. 这个创建进程的过程是调用前面讲到的startProcessLocked方法1(a) . 调用流程: 1(a) => 1(b) ==> 2(b). 下面再简单说说这4大组件与进程创建是在何时需要创建的. 2.2.1 Activity启动Activity过程: 调用startActivity,该方法经过层层调用,最终会调用ActivityStackSupervisor.java中的 [-> ActivityStackSupervisor.java] void startSpecificActivityLocked(...) { ProcessRecord app = mService.getProcessRecordLocked(r.processName, r.info.applicationInfo.uid, true); if (app != null && app.thread != null) { ... //进程已创建的case return } mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0, "activity", r.intent.getComponent(), false, false, true); } 2.2.2 Service启动服务过程: 调用startService,该方法经过层层调用,最终会调用ActiveServices.java中的 [-> ActiveServices.java] private final String bringUpServiceLocked(...){ ... ProcessRecord app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false); if (app == null) { if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags, "service", r.name, false, isolated, false)) == null) { ... } } ... } 2.2.3 ContentProviderContentProvider处理过程: 调用ContentResolver.query该方法经过层层调用, 最终会调用到AMS.java中的 [-> AMS.java] private final ContentProviderHolder getContentProviderImpl(...) { ... ProcessRecord proc = getProcessRecordLocked(cpi.processName, cpr.appInfo.uid, false); if (proc != null && proc.thread != null) { ... //进程已创建的case } else { proc = startProcessLocked(cpi.processName, cpr.appInfo, false, 0, "content provider", new ComponentName(cpi.applicationInfo.packageName,cpi.name), false, false, false); } ... } 2.2.4 Broadcast广播处理过程: 调用sendBroadcast,该方法经过层层调用, 最终会调用到BroadcastQueue.java中的 [-> BroadcastQueue.java] final void processNextBroadcast(boolean fromMsg) { ... ProcessRecord app = mService.getProcessRecordLocked(targetProcess, info.activityInfo.applicationInfo.uid, false); if (app != null && app.thread != null) { ... //进程已创建的case return } if ((r.curApp=mService.startProcessLocked(targetProcess, info.activityInfo.applicationInfo, true, r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND, "broadcast", r.curComponent, (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0, false, false)) == null) { ... } ... } 2.3 小节Activity, Service, ContentProvider, BroadcastReceiver这四大组件在启动时,当所承载的进程不存在时,都需要创建. 进程的创建过程交由系统进程system_server来完成的.
简称:
system_server拥有ATP/AMS, 每一个新创建的进程都会有一个相应的AT/AMS,从而可以跨进程 进行相互通信. 这便是进程创建过程的完整生态链. 三. 进程启动全过程前面刚已介绍四大组件的创建进程的过程是调用1(a) 3.1 AMS.startProcessLockedfinal 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; if (!isolated) { //根据进程名和uid检查相应的ProcessRecord app = getProcessRecordLocked(processName, info.uid, keepIfLarge); if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) { //如果当前处于后台进程,检查当前进程是否处于bad进程列表 if (mBadProcesses.get(info.processName, info.uid) != null) { return null; } } else { //当用户明确地启动进程,则清空crash次数,以保证其不处于bad进程直到下次再弹出crash对话框。 mProcessCrashTimes.remove(info.processName, info.uid); if (mBadProcesses.get(info.processName, info.uid) != null) { mBadProcesses.remove(info.processName, info.uid); if (app != null) { app.bad = false; } } } } else { //对于孤立进程,无法再利用已存在的进程 app = null; } //当存在ProcessRecord,且已分配pid(正在启动或者已经启动), // 且caller并不认为该进程已死亡或者没有thread对象attached到该进程.则不应该清理该进程 if (app != null && app.pid > 0) { if (!knownToBeDead || app.thread == null) { //如果这是进程中新package,则添加到列表 app.addPackage(info.packageName, info.versionCode, mProcessStats); return app; } //当ProcessRecord已经被attached到先前的一个进程,则杀死并清理该进程 killProcessGroup(app.info.uid, app.pid); handleAppDiedLocked(app, true, true); } String hostingNameStr = hostingName != null? hostingName.flattenToShortString() : null; if (app == null) { // 创建新的Process Record对象 app = newProcessRecordLocked(info, processName, isolated, isolatedUid); if (app == null) { return null; } app.crashHandler = crashHandler; } else { //如果这是进程中新package,则添加到列表 app.addPackage(info.packageName, info.versionCode, mProcessStats); } //当系统未准备完毕,则将当前进程加入到mProcessesOnHold if (!mProcessesReady && !isAllowedWhileBooting(info) && !allowWhileBooting) { if (!mProcessesOnHold.contains(app)) { mProcessesOnHold.add(app); } return app; } // 启动进程【见小节3.2】 startProcessLocked(app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs); return (app.pid != 0) ? app : null; } 主要功能:
3.2 AMS.startProcessLockedprivate final void startProcessLocked(ProcessRecord app, String hostingType, String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { long startTime = SystemClock.elapsedRealtime(); //当app的pid大于0且不是当前进程的pid,则从mPidsSelfLocked中移除该app.pid if (app.pid > 0 && app.pid != MY_PID) { synchronized (mPidsSelfLocked) { mPidsSelfLocked.remove(app.pid); mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); } app.setPid(0); } //从mProcessesOnHold移除该app mProcessesOnHold.remove(app); updateCpuStats(); //更新cpu统计信息 try { try { if (AppGlobals.getPackageManager().isPackageFrozen(app.info.packageName)) { //当前package已被冻结,则抛出异常 throw new RuntimeException("Package " + app.info.packageName + " is frozen!"); } } catch (RemoteException e) { throw e.rethrowAsRuntimeException(); } int uid = app.uid; int[] gids = null; int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; if (!app.isolated) { int[] permGids = null; try { //通过Package Manager获取gids final IPackageManager pm = AppGlobals.getPackageManager(); permGids = pm.getPackageGids(app.info.packageName, app.userId); MountServiceInternal mountServiceInternal = LocalServices.getService( MountServiceInternal.class); mountExternal = mountServiceInternal.getExternalStorageMountMode(uid, app.info.packageName); } catch (RemoteException e) { throw e.rethrowAsRuntimeException(); } //添加共享app和gids,用于app直接共享资源 if (ArrayUtils.isEmpty(permGids)) { gids = new int[2]; } else { gids = new int[permGids.length + 2]; System.arraycopy(permGids, 0, gids, 2, permGids.length); } gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid)); } //根据不同参数,设置相应的debugFlags ... app.gids = gids; app.requiredAbi = requiredAbi; app.instructionSet = instructionSet; boolean isActivityProcess = (entryPoint == null); if (entryPoint == null) entryPoint = "android.app.ActivityThread"; //请求Zygote创建新进程[见3.3] 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); ... if (app.persistent) { Watchdog.getInstance().processStarted(app.processName, startResult.pid); } //重置ProcessRecord的成员变量 app.setPid(startResult.pid); app.usingWrapper = startResult.usingWrapper; app.removed = false; app.killed = false; app.killedByAm = false; //将新创建的进程加入到mPidsSelfLocked synchronized (mPidsSelfLocked) { this.mPidsSelfLocked.put(startResult.pid, app); if (isActivityProcess) { Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); msg.obj = app; //延迟发送消息PROC_START_TIMEOUT_MSG mHandler.sendMessageDelayed(msg, startResult.usingWrapper ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); } } } catch (RuntimeException e) { app.setPid(0); //进程创建失败,则重置pid } }
关于Process.start()是通过socket通信告知Zygote创建fork子进程,创建新进程后将ActivityThread类加载到新进程,并调用ActivityThread.main()方法。详细过程见 理解Android进程创建流程 ,接下来进入AT.main方法. 3.3 ActivityThread.main[-> ActivityThread.java] public static void main(String[] args) { //性能统计默认是关闭的 SamplingProfilerIntegration.start(); //将当前进程所在userId赋值给sCurrentUser Environment.initForCurrentUser(); EventLogger.setReporter(new EventLoggingReporter()); AndroidKeyStoreProvider.install(); //确保可信任的CA证书存放在正确的位置 final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId()); TrustedCertificateStore.setDefaultUserDirectory(configDir); Process.setArgV0("<pre-initialized>"); //创建主线程的Looper对象, 该Looper是不运行退出 Looper.prepareMainLooper(); //创建ActivityThread对象 ActivityThread thread = new ActivityThread(); //建立Binder通道 【见流程3.4】 thread.attach(false); if (sMainThreadHandler == null) { sMainThreadHandler = thread.getHandler(); } // 当设置为true时,可打开消息队列的debug log信息 if (false) { Looper.myLooper().setMessageLogging(new LogPrinter(Log.DEBUG, "ActivityThread")); } Looper.loop(); //消息循环运行 throw new RuntimeException("Main thread loop unexpectedly exited"); }
之后主线程调用Looper.loop(),进入消息循环状态, 当没有消息时主线程进入休眠状态, 一旦有消息到来则唤醒主线程并执行相关操作. 3.4. ActivityThread.attach[-> ActivityThread.java] private void attach(boolean system) { sCurrentActivityThread = this; mSystemThread = system; if (!system) { //开启虚拟机的jit即时编译功能 ViewRootImpl.addFirstDrawHandler(new Runnable() { @Override public void run() { ensureJitEnabled(); } }); android.ddm.DdmHandleAppName.setAppName("<pre-initialized>", UserHandle.myUserId()); RuntimeInit.setApplicationObject(mAppThread.asBinder()); //创建ActivityManagerProxy对象 final IActivityManager mgr = ActivityManagerNative.getDefault(); try { //调用基于IActivityManager接口的Binder通道【见流程3.5】 mgr.attachApplication(mAppThread); } catch (RemoteException ex) { } //观察是否快接近heap的上限 BinderInternal.addGcWatcher(new Runnable() { @Override public void run() { if (!mSomeActivitiesChanged) { return; } Runtime runtime = Runtime.getRuntime(); long dalvikMax = runtime.maxMemory(); long dalvikUsed = runtime.totalMemory() - runtime.freeMemory(); if (dalvikUsed > ((3*dalvikMax)/4)) { mSomeActivitiesChanged = false; try { //当已用内存超过最大内存的3/4,则请求释放内存空间 mgr.releaseSomeActivities(mAppThread); } catch (RemoteException e) { } } } }); } else { ... } //添加dropbox日志到libcore DropBox.setReporter(new DropBoxReporter()); //添加Config回调接口 ViewRootImpl.addConfigCallback(new ComponentCallbacks2() { @Override public void onConfigurationChanged(Configuration newConfig) { synchronized (mResourcesManager) { if (mResourcesManager.applyConfigurationToResourcesLocked(newConfig, null)) { if (mPendingConfiguration == null || mPendingConfiguration.isOtherSeqNewer(newConfig)) { mPendingConfiguration = newConfig; sendMessage(H.CONFIGURATION_CHANGED, newConfig); } } } } @Override public void onLowMemory() { } @Override public void onTrimMemory(int level) { } }); } 对于非系统attach的处理 |
|
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系
[邮箱地址] 删除
|