Service启动过程and新进程创建全过程源码分析

xiaoxiao2021-02-28  77

由于Android本身对于四大组件的封装,导致在开发当中根本不需要知道四大组件的底层原理及运行过程,但是如果作为一个高级者来说或者为了解决一些底层出现的问题,那么了解四大组件的运行原理和启动过程那么非常必要的。而且目前市面上的热修复,插件化技术越来越火,那么如果连四大组件的启动过程和运行原理都不知道的话,那么也就根本就不明白这些技术的实现原理的,总之好处还是大大的,那么就让我们来一起研究一下吧。

在阅读源码以前还是先简要的说一下,其实四大组件的底层原理是用了Binder机制,那么如果对Binder机制一点都不了解的话,希望还是先看一下Binder机制,之前也有写一篇关于Binder的文章,希望可以有所帮助插件化知识详细分解及原理 之Binder机制

我们先说Service的启动过程,下面会说新进程的启动过程

一、Service的启动过程 :

启动Service的方式有两种,一种是startService和bindService,虽然调用的方法不同,但是其底层原理基本都一样,这里就从startService开始了,本文源码基于5.1

然后我们先看一下继承关系:

1、一般情况下我们都是在Activity当中通过调用startService来启动的,但是Activity并没有重写Context的startService方法,而是调用了ContextWrapper中的startService方法,那么我们就从这里开始了

源码路径: /frameworks/base/core/java/android/content/ContextWrapper.java

@Override public ComponentName startService(Intent service) { return mBase.startService(service); }

2、通过上面的代码我们看到他调用了mBase.startService(service)方法,mBase是什么我们看一下,然后我们进入他的startService再看

我们看到mBase是Context类型,而Context是一个抽象类,它的实现类是ContextImpl,那么我们就直接去看ContextImpl中的startService就好了 源码路径: /frameworks/base/core/java/android/app/ContextImpl.java

@Override public ComponentName startService(Intent service) { //这里只判断了是否是系统进程,如果是打了一段log,忽略 warnIfCallingFromSystemProcess(); //调用了本类的startServiceCommon方法 return startServiceCommon(service, mUser); }

3、上面又调用了ContextImpl类中的startServiceCommon方法,进去看看

private ComponentName startServiceCommon(Intent service, UserHandle user) { try { //验证Intent的信息是否有效,无效抛出异常 validateServiceIntent(service); service.prepareToLeaveProcess(); //这里又调用了ActivityManagerNative中startService ComponentName cn = ActivityManagerNative.getDefault().startService( mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(getContentResolver()), user.getIdentifier()); //对远程调用的结果验证 if (cn != null) { if (cn.getPackageName().equals("!")) { throw new SecurityException( "Not allowed to start service " + service + " without permission " + cn.getClassName()); } else if (cn.getPackageName().equals("!!")) { throw new SecurityException( "Unable to start service " + service + ": " + cn.getClassName()); } } return cn; } catch (RemoteException e) { return null; } }

4、上面又转到了ActivityManagerNative.getDefault().startService当中,而ActivityManagerNative.getDefault()是一个Binder对象,我们看一下 源码路径: /frameworks/base/core/java/android/app/ActivityManagerNative.java

//ActivityManagerNative 类继承Binder 实现了IActivityManager public abstract class ActivityManagerNative extends Binder implements IActivityManager { ... //getDefault方法返回了gDefault.get() static public IActivityManager getDefault() { return gDefault.get(); } //gDefault是一个单例, private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>() { protected IActivityManager create() { //获取ActivityManagerService IBinder b = ServiceManager.getService("activity"); if (false) { Log.v("ActivityManager", "default service binder = " + b); } //远程调用将ACtivityManagerService的代理类 IActivityManager am = asInterface(b); if (false) { Log.v("ActivityManager", "default service = " + am); } return am; } }; //asInterface方法将返回ActivityManagerService的代理类 static public IActivityManager asInterface(IBinder obj) { if (obj == null) { return null; } //查询是否是本地调用 IActivityManager in = (IActivityManager)obj.queryLocalInterface(descriptor); if (in != null) { return in; } //返回代理 return new ActivityManagerProxy(obj); } ... }

5、通过上面的代码我们可以知道ActivityManagerNative.getDefault()返回的是ActivityManagerService的代理类,也就是ActivityManagerProxy,而ActivityManagerProxy是ActivityManagerNative的内部类其中的startService也只是发起了远程调用,最终会调用到ActivityManagerService中的startService方法,这里有不明白的请先看插件化知识详细分解及原理 之Binder机制

6、上面的代码会转到ActivityManagerService当中,调用startService方法,下面我们就去看ActivityManagerService当中的startService 源码路径: /frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { public ActivityManagerService(Context systemContext) { ... //构造方法中初始化了mServices mServices = new ActiveServices(this); ... } @Override public ComponentName startService(IApplicationThread caller, Intent service, String resolvedType, int userId) { ... //调用了mServices的startServiceLocked方法 ComponentName res = mServices.startServiceLocked(caller, service, resolvedType, callingPid, callingUid, userId); Binder.restoreCallingIdentity(origId); return res; } } }

7、上面的代码又转到了ActiveServices中的startServiceLocked方法中,继续跟进 源码路径: /frameworks/base/services/core/java/com/android/server/am/ActiveServices.java

ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType, int callingPid, int callingUid, int userId) { if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "startService: " + service + " type=" + resolvedType + " args=" + service.getExtras()); final boolean callerFg; //这里的caller是调用者所在的ActivityThread中的内部类ApplicationThread,它也是一个Binder对象 //主要用来和应用进程进行通信 if (caller != null) { final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller); if (callerApp == null) { throw new SecurityException( "Unable to find app for caller " + caller + " (pid=" + Binder.getCallingPid() + ") when starting service " + service); } callerFg = callerApp.setSchedGroup != Process.THREAD_GROUP_BG_NONINTERACTIVE; } else { callerFg = true; } //retrieveServiceLocked是解析Intent对象,从ActivityManagerService中取这个进程中 //的ServiceMap,然后从ServiceMap当中看是否存在这个service的ServiceRecord, //如果不存在则创建一个ServiceRecord,ServiceRecord是用来记录这个service的各种信息的, //包括属于哪个进程,service的名称,应用包名等等,然后将ServiceRecord存入ActivityManagerService //的成员变量mServiceMap当中 ServiceLookupResult res = retrieveServiceLocked(service, resolvedType, callingPid, callingUid, userId, true, callerFg); if (res == null) { return null; } if (res.record == null) { return new ComponentName("!", res.permission != null ? res.permission : "private to package"); } ServiceRecord r = res.record; ... //接着调用本类的startServiceInnerLocked方法 return startServiceInnerLocked(smap, service, r, callerFg, addToStarting); }

8、上面说到了ServiceRecord,ServiceRecord是用来记录这个service的各种信息的,包括属于哪个进程,service的名称,应用包名等等

ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r, boolean callerFg, boolean addToStarting) { .... //又转到了bringUpServiceLocked方法 String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false); if (error != null) { return new ComponentName("!!", error); } .... return r.name; }

9、点进去,接着看bringUpServiceLocked方法

private final String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg, boolean whileRestarting) { ... //判断要启动的Service是否已经启动,如果启动只调用onStartCommand方法,下面再分析这个方法 if (r.app != null && r.app.thread != null) { sendServiceArgsLocked(r, execInFg, false); return null; } ..... final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != ; final String procName = r.processName; ProcessRecord app; //判断要启动的这个service是否配置了要在独立进程中启动,之前是否加载过这个进程 if (!isolated) { app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false); if (DEBUG_MU) Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid + " app=" + app); //之前加载过该进程,不需要再创建 if (app != null && app.thread != null) { try { app.addPackage(r.appInfo.packageName, r.appInfo.versionCode, mAm.mProcessStats); //启动service,一会分析 realStartServiceLocked(r, app, execInFg); return null; } catch (RemoteException e) { Slog.w(TAG, "Exception when starting service " + r.shortName, e); } // If a dead object exception was thrown -- fall through to // restart the application. } } else { app = r.isolatedProc; } // Not running -- get it started, and enqueue this service record // to be executed when the app comes up. if (app == null) { //没有加载过这个进程,创建一个新的进程,然后启动service if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags, "service", r.name, false, isolated, false)) == null) { String msg = "Unable to launch app " + r.appInfo.packageName + "/" + r.appInfo.uid + " for service " + r.intent.getIntent() + ": process is bad"; Slog.w(TAG, msg); //启动service,一会分析 bringDownServiceLocked(r); return msg; } if (isolated) { r.isolatedProc = app; } } //保存这个ServiceRecord if (!mPendingServices.contains(r)) { mPendingServices.add(r); } .... return null; }

10、在即将启动service的时候突然出现了三种情况,我们总结一下

v1:要启动的Service是否已经启动,调用了sendServiceArgsLocked方法

v2:Service没有启动,但是需要启动这个service的进程已经存在,调用了realStartServiceLocked方法

v3:Service没有启动,但是需要启动这个service的进程不存在,调用了bringDownServiceLocked

v1.1、我们先来看如果这个service已经启动的情况,即sendServiceArgsLocked方法:

private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg, boolean oomAdjusted) { .... //调用了r.app.thread,这个参数其实就是上面说过的ActivitiyThread中的内部类ApplicationThread r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent); .... }

v1.2、上面调用了ActivitiyThread中的内部类ApplicationThread的scheduleServiceArgs方法,那么我们就去找这个方法就好了 源码路径: /frameworks/base/core/java/android/app/ActivityThread.java

private class ApplicationThread extends ApplicationThreadNative { .... public final void scheduleServiceArgs(IBinder token, boolean taskRemoved, int startId, int flags ,Intent args) { ServiceArgsData s = new ServiceArgsData(); s.token = token; s.taskRemoved = taskRemoved; s.startId = startId; s.flags = flags; s.args = args; //这里是要发送一条消息 sendMessage(H.SERVICE_ARGS, s); } .... } private void sendMessage(int what, Object obj) { sendMessage(what, obj, 0, 0, false); } private void sendMessage(int what, Object obj, int arg1) { sendMessage(what, obj, arg1, 0, false); } private void sendMessage(int what, Object obj, int arg1, int arg2) { sendMessage(what, obj, arg1, arg2, 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); }

v1.3、上面所有的发送消息的方法最终都会走到参数最多的那个,然后通过mH发送了一条消息,而mH其实就是一个Handler,也是在ActivityThread当中通过内部类的方式创建的,上面发送的是H.SERVICE_ARGS,我们去找这个对应的常量就好了

case SERVICE_ARGS: Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStart"); //调用service的onStartCommand方法 handleServiceArgs((ServiceArgsData)msg.obj); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); break;

v1.4、在接着看ActivityThread当中的handleServiceArgs方法

private void handleServiceArgs(ServiceArgsData data) { //从map中取出service,因为这里已经启动的service Service s = mServices.get(data.token); if (s != null) { try { if (data.args != null) { data.args.setExtrasClassLoader(s.getClassLoader()); data.args.prepareToEnterProcess(); } int res; if (!data.taskRemoved) { //回调service的onStartCommand方法 res = s.onStartCommand(data.args, data.flags, data.startId); } else { s.onTaskRemoved(data.args); res = Service.START_TASK_REMOVED_COMPLETE; } QueuedWork.waitToFinish(); try { //告诉ActivityManagerService,onStartCommand方法已经回调完毕 ActivityManagerNative.getDefault().serviceDoneExecuting( data.token, SERVICE_DONE_EXECUTING_START, data.startId, res); } catch (RemoteException e) { // nothing to do. } ensureJitEnabled(); } catch (Exception e) { if (!mInstrumentation.onException(s, e)) { throw new RuntimeException( "Unable to start service " + s + " with " + data.args + ": " + e.toString(), e); } } } }

v1.5、好了,到这里我们就分析完了启动service时的第一种情况,也就是这个service已经被启动了后再次调用startService方法的流程

v2、1:Service没有启动,但是需要启动这个service的进程已经存在,调用了realStartServiceLocked方法,

private final void realStartServiceLocked(ServiceRecord r, ProcessRecord app, boolean execInFg) throws RemoteException { .... //启动创建service app.thread.scheduleCreateService(r, r.serviceInfo, .... //绑定service,即 requestServiceBindingsLocked(r, execInFg); .... //调用service的onStartCommand方法,上边分析过这个方法了 sendServiceArgsLocked(r, execInFg, true); .... }

v2、2上面的几个方法都和第一个分析调用onStartCommand的方式一样,只不过调用的方法不同,下面不再贴代码了,我们看一下最后一种创建进程的那种情况

二、新进程启动过程 :

v3.1、Service没有启动,但是需要启动这个service的进程不存在,调用了bringDownServiceLocked,我们再看一下最会出现三种情况的那个方法,这里我们也只分析创建进程的这一部分,其余的原理和步骤都和上边分析的相同。

private final String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg, boolean whileRestarting) { ... //省略前两种情况了,已经分析过 if (app == null) { //没有加载过这个进程,创建一个新的进程,然后启动service if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags, "service", r.name, false, isolated, false)) == null) { String msg = "Unable to launch app " + r.appInfo.packageName + "/" + r.appInfo.uid + " for service " + r.intent.getIntent() + ": process is bad"; Slog.w(TAG, msg); //启动service,一会分析 bringDownServiceLocked(r); return msg; } if (isolated) { r.isolatedProc = app; } } //保存这个ServiceRecord if (!mPendingServices.contains(r)) { mPendingServices.add(r); } .... return null; }

v3.2、上面判断如果需要创建进程的话是通过调用mAm.startProcessLocked生成了进程,mAm就是AMS,我们直接看startProcessLocked方法

private final void startProcessLocked(ProcessRecord app, String hostingType, String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) { long startTime = SystemClock.elapsedRealtime(); ..... try { ..... //注意看如果entryPoint等于null的话,会被赋值android.app.ActivityThread boolean isActivityProcess = (entryPoint == null); if (entryPoint == null) entryPoint = "android.app.ActivityThread"; checkTime(startTime, "startProcess: asking zygote to start proc"); //启动进程 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); checkTime(startTime, "startProcess: returned from zygote!"); .... } catch (RuntimeException e) { ..... } }

v3.3、指定了ActivityThread的这个类后,在创建进程完成后会调用ActivityThread的main方法,生成进程的代码在Process.java中,想去深入了解的自行查阅,我们再去看ActivityThread 源码路径: /frameworks/base/core/java/android/app/ActivityThread.java

public final class ActivityThread { .... //直接创建了一个ApplicationThread类型的mAppThread成员变量 final ApplicationThread mAppThread = new ApplicationThread(); .... //main方法 public static void main(String[] args) { SamplingProfilerIntegration.start(); .... //创建Looper Looper.prepareMainLooper(); //创建自己的实例 ActivityThread thread = new ActivityThread(); //准备和AMS绑定 thread.attach(false); if (sMainThreadHandler == null) { sMainThreadHandler = thread.getHandler(); } if (false) { Looper.myLooper().setMessageLogging(new LogPrinter(Log.DEBUG, "ActivityThread")); } //开启Looper循环 Looper.loop(); throw new RuntimeException("Main thread loop unexpectedly exited"); } //这里和AMS绑定,system代表是否为系统进程 private void attach(boolean system) { sCurrentActivityThread = this; mSystemThread = system; if (!system) { .... RuntimeInit.setApplicationObject(mAppThread.asBinder()); final IActivityManager mgr = ActivityManagerNative.getDefault(); try { //和AMS绑定 mgr.attachApplication(mAppThread); } catch (RemoteException ex) { // Ignore } .... } else { //是系统进程 android.ddm.DdmHandleAppName.setAppName("system_process", UserHandle.myUserId()); try { mInstrumentation = new Instrumentation(); ContextImpl context = ContextImpl.createAppContext( this, getSystemContext().mPackageInfo); mInitialApplication = context.mPackageInfo.makeApplication(true, null); mInitialApplication.onCreate(); } catch (Exception e) { throw new RuntimeException( "Unable to instantiate Application():" + e.toString(), e); } } // add dropbox logging to libcore DropBox.setReporter(new DropBoxReporter()); //ViewRootImpl添加onConfigurationChanged 、 onLowMemory 、 onTrimMemory等方法回调 ViewRootImpl.addConfigCallback(new ComponentCallbacks() { @Override public void onConfigurationChanged(Configuration newConfig) { synchronized (mResourcesManager) { // We need to apply this change to the resources // immediately, because upon returning the view // hierarchy will be informed about it. if (mResourcesManager.applyConfigurationToResourcesLocked(newConfig, null)) { // This actually changed the resources! Tell // everyone about it. if (mPendingConfiguration == null || mPendingConfiguration.isOtherSeqNewer(newConfig)) { mPendingConfiguration = newConfig; sendMessage(H.CONFIGURATION_CHANGED, newConfig); } } } } @Override public void onLowMemory() { } @Override public void onTrimMemory(int level) { } }); } }

v3.4、这里调用了ActivityManagerNative.getDefault()的attachApplication方法,我们上面分析过ActivityManagerNative.getDefault()返回的是AMS的代理里,那么我们直接去看AMS中的attachApplication方法 源码路径: /frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

@Override public final void attachApplication(IApplicationThread thread) { synchronized (this) { int callingPid = Binder.getCallingPid(); final long origId = Binder.clearCallingIdentity(); //调用了本类的attachApplicationLocked方法 attachApplicationLocked(thread, callingPid); Binder.restoreCallingIdentity(origId); } }

v3.5、再看一下attachApplicationLocked

private final boolean attachApplicationLocked(IApplicationThread thread, int pid) { ..... ApplicationInfo appInfo = app.instrumentationInfo != null ? app.instrumentationInfo : app.info; app.compat = compatibilityInfoForPackageLocked(appInfo); if (profileFd != null) { profileFd = profileFd.dup(); } ProfilerInfo profilerInfo = profileFile == null ? null : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); //调用了传进来的ActivityThread的内部类ApplicationThread的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()); updateLruProcessLocked(app, false, null); app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); } catch (Exception e) { Slog.wtf(TAG, "Exception thrown during bind of " + app, e); app.resetPackageList(mProcessStats); app.unlinkDeathRecipient(); startProcessLocked(app, "bind fail", processName); return false; } ...... //上面创建Application后再进一步操作Serivice,一会反回来分析 if (!badApp) { try { didSomething |= mServices.attachApplicationLocked(app, processName); } catch (Exception e) { Slog.wtf(TAG, "Exception thrown starting services in " + app, e); badApp = true; } } return true; }

v3.6、attachApplicationLocked的代码非常的多,我们只看相关代码 ,这里调用了刚刚传进来的ActivityThread内部类ApplicationThread的 bindApplication方法,我们再返回ActivityThread中看 源码路径: /frameworks/base/core/java/android/app/ActivityThread.java

public final void bindApplication(String processName, ApplicationInfo appInfo, List<ProviderInfo> providers, ComponentName instrumentationName, ProfilerInfo profilerInfo, Bundle instrumentationArgs, IInstrumentationWatcher instrumentationWatcher, IUiAutomationConnection instrumentationUiConnection, int debugMode, boolean enableOpenGlTrace, boolean isRestrictedBackupMode, boolean persistent, Configuration config, CompatibilityInfo compatInfo, Map<String, IBinder> services, Bundle coreSettings) { .... //创建绑定数据 AppBindData data = new AppBindData(); data.processName = processName; data.appInfo = appInfo; data.providers = providers; data.instrumentationName = instrumentationName; data.instrumentationArgs = instrumentationArgs; data.instrumentationWatcher = instrumentationWatcher; data.instrumentationUiAutomationConnection = instrumentationUiConnection; data.debugMode = debugMode; data.enableOpenGlTrace = enableOpenGlTrace; data.restrictedBackupMode = isRestrictedBackupMode; data.persistent = persistent; data.config = config; data.compatInfo = compatInfo; data.initProfilerInfo = profilerInfo; //发送消息到Handler中 sendMessage(H.BIND_APPLICATION, data); }

v3.7、我们上面也分析过消息会发送到ActivityThread中的内部类Handler中,我们找一个这个常量指定的处理

case BIND_APPLICATION: Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication"); //拿到刚才创建的绑定数据 AppBindData data = (AppBindData)msg.obj; //调用了handleBindApplication方法 handleBindApplication(data); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); break;

v3.8、我们再去看一下handleBindApplication

private void handleBindApplication(AppBindData data) { .... //创建上下文对象 final ContextImpl appContext = ContextImpl.createAppContext(this, data.info); .... //准备初始化的数据 if (data.instrumentationName != null) { InstrumentationInfo ii = null; try { ii = appContext.getPackageManager(). getInstrumentationInfo(data.instrumentationName, ); } catch (PackageManager.NameNotFoundException e) { } if (ii == null) { throw new RuntimeException( "Unable to find instrumentation info for: " + data.instrumentationName); } mInstrumentationPackageName = ii.packageName; mInstrumentationAppDir = ii.sourceDir; mInstrumentationSplitAppDirs = ii.splitSourceDirs; mInstrumentationLibDir = ii.nativeLibraryDir; mInstrumentedAppDir = data.info.getAppDir(); mInstrumentedSplitAppDirs = data.info.getSplitAppDirs(); mInstrumentedLibDir = data.info.getLibDir(); //准备创建Application的数据 ApplicationInfo instrApp = new ApplicationInfo(); instrApp.packageName = ii.packageName; instrApp.sourceDir = ii.sourceDir; instrApp.publicSourceDir = ii.publicSourceDir; instrApp.splitSourceDirs = ii.splitSourceDirs; instrApp.splitPublicSourceDirs = ii.splitPublicSourceDirs; instrApp.dataDir = ii.dataDir; instrApp.nativeLibraryDir = ii.nativeLibraryDir; //LoadedApk对象是APK文件在内存中的表示。 //Apk文件的相关信息,诸如Apk文件的代码和资源,甚至代码里面的Activity,Service等四大组件的信息我们都可以通过此对象获取 LoadedApk pi = getPackageInfo(instrApp, data.compatInfo, appContext.getClassLoader(), false, true, false); //创建新进程的Context ContextImpl instrContext = ContextImpl.createAppContext(this, pi); try { //创建Instrumentation对象 java.lang.ClassLoader cl = instrContext.getClassLoader(); mInstrumentation = (Instrumentation) cl.loadClass(data.instrumentationName.getClassName()).newInstance(); } catch (Exception e) { throw new RuntimeException( "Unable to instantiate instrumentation " + data.instrumentationName + ": " + e.toString(), e); } //初始化Instrumentation mInstrumentation.init(this, instrContext, appContext, new ComponentName(ii.packageName, ii.name), data.instrumentationWatcher, data.instrumentationUiAutomationConnection); .... } else { mInstrumentation = new Instrumentation(); } .... try { //通过创建Application并回调Application的attach方法 Application app = data.info.makeApplication(data.restrictedBackupMode, null); mInitialApplication = app; .... try { //回调Application的OnCreate方法 mInstrumentation.callApplicationOnCreate(app); } catch (Exception e) { if (!mInstrumentation.onException(app, e)) { throw new RuntimeException( "Unable to create application " + app.getClass().getName() + ": " + e.toString(), e); } } } finally { StrictMode.setThreadPolicy(savedPolicy); } }

v3.9、这里不要蒙啊,这里是创建了新的进程,所以应该也就知道了每个进程都会创建一个Application对象,到这里新进程的创建就完了,我们总结一下

总结进程启动:新进程通过调用Process.start的方法启动一个进程,然后因为指定了android.app.ActivityThread的这个类,所以在创建进程之后会调用android.app.ActivityThread类中的main方法,在main方法中会开启消息循环,然后创建了一个ActivityThread实例,调用attach方法,在attach方法中,通过AMS.attachApplication方法,将ActivityThread当中的内部类ApplicationThread和AMS绑定,之后这个进程的所有通信全部都是靠ApplicationThread和AMS和ActivityThread中的Handler来进行,希望本能能对大家有所帮助,从一个启动的过程可以窥视Android的通信机制及运行原理。

好了,我们在返回到v3.5中AMS中的attachApplicationLocked方法,我们在贴一下代码

private final boolean attachApplicationLocked(IApplicationThread thread, int pid) { ..... ApplicationInfo appInfo = app.instrumentationInfo != null ? app.instrumentationInfo : app.info; app.compat = compatibilityInfoForPackageLocked(appInfo); if (profileFd != null) { profileFd = profileFd.dup(); } ProfilerInfo profilerInfo = profileFile == null ? null : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop); //调用了传进来的ActivityThread的内部类ApplicationThread的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()); updateLruProcessLocked(app, false, null); app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis(); } catch (Exception e) { Slog.wtf(TAG, "Exception thrown during bind of " + app, e); app.resetPackageList(mProcessStats); app.unlinkDeathRecipient(); startProcessLocked(app, "bind fail", processName); return false; } ...... //上面创建Application后再进一步操作Serivice,一会反回来分析 if (!badApp) { try { didSomething |= mServices.attachApplicationLocked(app, processName); } catch (Exception e) { Slog.wtf(TAG, "Exception thrown starting services in " + app, e); badApp = true; } } return true; }

在上面我们都已经分析了bindApplication方法,也就是创建Application对象回调相应生命周期等,然后代码接着往下走到mServices.attachApplicationLocked,mServices就是上面分析过的ActiveServices,所有启动service的操作都在这个类里,我们进去看看这个方法。 源码路径: /frameworks/base/services/core/java/com/android/server/am/ActiveServices.java

boolean attachApplicationLocked(ProcessRecord proc, String processName) throws RemoteException { boolean didSomething = false; // Collect any services that are waiting for this process to come up. if (mPendingServices.size() > ) { ServiceRecord sr = null; try { for (int i=; i<mPendingServices.size(); i++) { sr = mPendingServices.get(i); if (proc != sr.isolatedProc && (proc.uid != sr.appInfo.uid || !processName.equals(sr.processName))) { continue; } mPendingServices.remove(i); i--; proc.addPackage(sr.appInfo.packageName, sr.appInfo.versionCode, mAm.mProcessStats); //又调用了上面分析过的方法,这个方法曾经在出现三种情况的方法里出现过,当 //时是第二种情况:如果service没有启动,但是service所在进程已经启动会调用这个方法 realStartServiceLocked(sr, proc, sr.createdFromFg); didSomething = true; } } catch (RemoteException e) { throw e; } } .... return didSomething; }

这个方法又调用了当时在第9步中的第二种情况的方法,就是service没有启动,但是service所在进程已经存在的情况,当时我们这个方法没有具体分析,现在我们再去看看 源码路径: /frameworks/base/services/core/java/com/android/server/am/ActiveServices.java

private final void realStartServiceLocked(ServiceRecord r, ProcessRecord app, boolean execInFg) throws RemoteException { .... //启动创建service app.thread.scheduleCreateService(r, r.serviceInfo, .... //绑定service, requestServiceBindingsLocked(r, execInFg); .... //调用service的onStartCommand方法,上边分析过这个方法了 sendServiceArgsLocked(r, execInFg, true); .... }

这里我们继续分析service创建的过程,其他的步骤都是一个原理,创建service调用了ActivityThread中的scheduleCreateService 源码路径:

public final void scheduleCreateService(IBinder token, ServiceInfo info, CompatibilityInfo compatInfo, int processState) { updateProcessState(processState, false); CreateServiceData s = new CreateServiceData(); s.token = token; s.info = info; s.compatInfo = compatInfo; //发消息到Handler sendMessage(H.CREATE_SERVICE, s); }

到Handler中找到常量CREATE_SERVICE对应的处理

case CREATE_SERVICE: Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceCreate"); //调用 handleCreateService handleCreateService((CreateServiceData)msg.obj); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); break;

再看一下handleCreateService方法

private void handleCreateService(CreateServiceData data) { // If we are getting ready to gc after going to the background, well // we are back active so skip it. unscheduleGcIdler(); //LoadedApk是LoadedApk对象是APK文件在内存中的表示。 //Apk文件的相关信息,诸如Apk文件的代码和资源, //甚至代码里面的Activity,Service等四大组件的信息我们都可以通过此对象获取。 LoadedApk packageInfo = getPackageInfoNoCheck( data.info.applicationInfo, data.compatInfo); Service service = null; try { //加载service类 java.lang.ClassLoader cl = packageInfo.getClassLoader(); service = (Service) cl.loadClass(data.info.name).newInstance(); } catch (Exception e) { if (!mInstrumentation.onException(service, e)) { throw new RuntimeException( "Unable to instantiate service " + data.info.name + ": " + e.toString(), e); } } try { ContextImpl context = ContextImpl.createAppContext(this, packageInfo); context.setOuterContext(service); //判断Application是否创建,没有创建会创建Application对象, //但是在上面创建进程的时候已经创建,所以会直接返回 Application app = packageInfo.makeApplication(false, mInstrumentation); //初始化service service.attach(context, this, data.info.name, data.token, app, ActivityManagerNative.getDefault()); //调用service的 onCreate方法 service.onCreate(); //存储service的信息 mServices.put(data.token, service); try { //通知AMS已经创建完毕 ActivityManagerNative.getDefault().serviceDoneExecuting( data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0); } catch (RemoteException e) { // nothing to do. } } catch (Exception e) { if (!mInstrumentation.onException(service, e)) { throw new RuntimeException( "Unable to create service " + data.info.name + ": " + e.toString(), e); } } }

handleCreateService方法主要是加载Service类,初始化Service,调用Service的onCreate方法,保存Service信息,方便下次使用。这个方法结束后Service就启动起来,realStartServiceLocked中的方法会继续向下走,但是几乎都是这个逻辑,通过ApplicationThread发送消息到ActivityThread的Handler中处理,处理后通过AMS在通知ActivityThread中的处理完毕等。

下面我们总结一下: 1。首先startService方法在ContextWrapper中,ContextWrapper又调用了Context中的startService,Context的实现类是ContextImpl

2。在ContextImpl在构造方法中创建了一个叫ActiveServices的类,在ContextImpl的startService方法中调用了ActiveServices中的startServiceLocked,后续到了ActiveServices的bringUpServiceLocked方法中出现了三种情况

2.1 service已经启动,直接通过ActivityThread发送消息到Handler中调用startCommand方法

2.2 Service没有启动,但是service所属进程已经创建,调用realStartServiceLocked方法。发送消息到Handler中,加载Service类,初始化Service,调用Service的onCreate方法,保存Service信息,然后realStartServiceLocked方法将继续执行绑定,调用startCommand的方法,逻辑和启动一样类似

2.3 Service没有启动,而且Service所属进程也没有创建,这时会通过AMS的startProcessLocked方法中通过Process.start方法创建一个新的进程,然后调用新进程的ActivityThread的main方法,在main方法中将绑定AMS,在AMS的bindApplicationLocked中新创建Application后调用了ActiveServices.attachApplicationLocked方法,然后调用了realStartServiceLocked方法相应的创建Service,绑定Service,调用startCommand方法。

OK,到这里就分析完了,后续会有其他组件源码分析,敬请期待

转载请注明原文地址: https://www.6miu.com/read-78569.html

最新回复(0)