2.6Service启动流程
目录介绍
- 01.startService源码分析
- 1.1 ContextImpl类中startService()
- 1.2 ActivityManagerService中startService()
- 02.ActivityThread启动
- 2.1 ActivityThread类中main()方法
- 2.2 ActivityThread类中scheduleCreateService()
- 03.bindService源码分析
- 3.1 绑定一个服务
- 3.2 ContextImpl类中bindService()
01.startService源码分析
1.1 ContextImpl类中startService()
- 在 Activity 中使用的 startService 方法是定义在 Context 的抽象类中,它的真正实现类是 ContextImpl,所以先进入 ContextImpl 类。
- 先从startService开始,然后进入本类的startServiceCommon方法,并最终调用ActivityManagerNative.getDefault()对象的 startService 方法。
- ActivityManager.getService()获取到IActivityManager对象,并且是通过单利模式创建的。
@Override public ComponentName startService(Intent service) { warnIfCallingFromSystemProcess(); return startServiceCommon(service, false, mUser); } private ComponentName startServiceCommon(Intent service, boolean requireForeground, UserHandle user) { try { validateServiceIntent(service); service.prepareToLeaveProcess(this); ComponentName cn = ActivityManager.getService().startService( mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded( getContentResolver()), requireForeground, getOpPackageName(), 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()); } else if (cn.getPackageName().equals("?")) { throw new IllegalStateException( "Not allowed to start service " + service + ": " + cn.getClassName()); } } return cn; } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } }
- 然后看一下validateServiceIntent(service)源码
- 可以知道如果intent不是new Intent(context,XxService.class),那么就会抛出异常
private void validateServiceIntent(Intent service) { if (service.getComponent() == null && service.getPackage() == null) { if (getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP) { IllegalArgumentException ex = new IllegalArgumentException( "Service Intent must be explicit: " + service); throw ex; } else { Log.w(TAG, "Implicit intents with startService are not safe: " + service + " " + Debug.getCallers(2, 3)); } } }
- 然后看看ActivityManager.getService()的代码
public static IActivityManager getService() { return IActivityManagerSingleton.get(); } private static final Singleton<IActivityManager> IActivityManagerSingleton = new Singleton<IActivityManager>() { @Override protected IActivityManager create() { final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE); final IActivityManager am = IActivityManager.Stub.asInterface(b); return am; } };
1.2 ActivityManagerService中startService()
- 这里调用 mServices 对象的 startServiceLocked 方法,这里的 mServices 对象是 ActiveServices 类
@Override public ComponentName startService(IApplicationThread caller, Intent service, String resolvedType, int userId) { enforceNotIsolatedCaller("startService"); //...... synchronized(this) { final int callingPid = Binder.getCallingPid(); final int callingUid = Binder.getCallingUid(); final long origId = Binder.clearCallingIdentity(); ComponentName res = mServices.startServiceLocked(caller, service, resolvedType, callingPid, callingUid, userId); Binder.restoreCallingIdentity(origId); return res; } }
- 接着看mServices.startServiceLocked方法,点击去看看源码
- 下面代码中省略了很多的源代码,源码实在太多呢
- 通过 retrieveServiceLocked 方法来解析 service 这个 Intent,就是解析前面我们在 AndroidManifest.xml 定义的 Service 标签的 intent-filter 相关内容,然后将解析结果放在 res.record 中,再调用 startServiceInnerLocked 方法。startServiceInnerLocked 方法中会调用 bringUpServiceLocked 方法。
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType, int callingPid, int callingUid, int userId) { ServiceLookupResult res = retrieveServiceLocked(service, resolvedType, callingPid, callingUid, userId, true, callerFg); ServiceRecord r = res.record; //这里紧接着会调用 startServiceInnerLocked 方法 return startServiceInnerLocked(smap, service, r, callerFg, addToStarting); } ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r, boolean callerFg, boolean addToStarting) { synchronized (r.stats.getBatteryStats()) { r.stats.startRunningLocked(); } //这里紧接着会调用 bringUpServiceLocked 方法 String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false); }
- 接着看看bringUpServiceLocked()这个方法源码,比较重要
- 可以看到,当 Service 所在的进程存在时,将调用realStartServiceLocked 方法来启动 Service,否则的话调用 startProcessLocked 方法来启动新进程。
private final String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg, boolean whileRestarting) { //(1)这里如果当前的 ProcessRecord 不为 null,那就不需要重新创建进程, //而是调用 realStartServiceLocked 方法来启动 Service if (app != null && app.thread != null) { try { app.addPackage(r.appInfo.packageName, r.appInfo.versionCode, mAm.mProcessStats); realStartServiceLocked(r, app, execInFg); return null; } catch (RemoteException e) { Slog.w(TAG, "Exception when starting service " + r.shortName, e); } } //(2)如果是需要创建新进程,那么将调用 ActivityManagerService.startProcessLocked 方法来启动新进程 if (app == null) { if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags, "service", r.name, false, isolated, false)) == null) { //...... bringDownServiceLocked(r); return msg; } if (isolated) { r.isolatedProc = app; } } //最后将 ServiceRecord 保存到成员变量 mPendingServices 中 if (!mPendingServices.contains(r)) { mPendingServices.add(r); } }
- 最后看看startProcessLocked()这里面的代码,如下所示
- 通过 Process 的 start 方法启动ActivityThread的新进程,进入该类的 main 方法。
//在ActivityManagerService类中 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"; checkTime(startTime, "startProcess: asking zygote to start proc"); //通过 processName,uid 等启动新进程 Process.start(entryPoint, app.processName, uid, uid, gids, debugFlags, mountExternal, app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet, app.info.dataDir, entryPointArgs); } //在Process类中 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); }
02.ActivityThread启动
2.1 ActivityThread类中main()方法
- main()方法源码如下所示
- 1.绑定应用进程到ActivityManagerService
- 在 Android 应用程序中,每一个进程对应一个 ActivityThread 实例,然后这里创建了 ActivityThread 对象并调用了其 attach 方法
- 2.主线程Handler消息处理
- 启动looper轮询器,所以在activity或者service创建handler对象时,不需要手动调用looper。原因就是在这里
- 首先Looper.prepareMainLooper();是为主线程创建了Looper,然后thread.getHandler();是保存了主线程的Handler,最后Looper.loop();进入消息循环。
public static void main(String[] args) { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain"); 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 对象 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"); }
- 1.绑定应用进程到ActivityManagerService
- 接着看看thread.attach(false)方法代码
- main()方法通过thread.attach(false)绑定应用进程。ActivityManagerNative通过getDefault()方法返回ActivityManagerService实例,ActivityManagerService通过attachApplication将ApplicationThread对象绑定到ActivityManagerService,而ApplicationThread作为Binder实现ActivityManagerService对应用进程的通信和控制。
- 在ActivityManagerService内部,attachApplication实际是通过调用attachApplicationLocked实现的,这里采用了synchronized关键字保证同步。
private void attach(boolean system) { final IActivityManager mgr = ActivityManagerNative.getDefault(); try { //这里调用了 ActivityManagerProxy.attachApplication 方法。 mgr.attachApplication(mAppThread); } catch (RemoteException ex) { // Ignore } } //然后看看attachApplication方法 @Override public final void attachApplication(IApplicationThread thread) { synchronized (this) { int callingPid = Binder.getCallingPid(); final long origId = Binder.clearCallingIdentity(); attachApplicationLocked(thread, callingPid); Binder.restoreCallingIdentity(origId); } }
- 接着看看attachApplicationLocked(thread, callingPid)方法代码
- 如果是启动 Service 将调用 ActiveServices 对象的 attachApplicationLocked 方法,而如果是启动 Activity 将调用 ActivityStackSupervisor 对象的 attachApplicationLocked 方法。
- attachApplicationLocked的实现较为复杂,其主要功能分为两部分:
- thread.bindApplication
- mStackSupervisor.attachApplicationLocked(app)
private final boolean attachApplicationLocked(IApplicationThread thread,int pid) { if (app.instr != null) { thread.bindApplication(processName, appInfo, providers, app.instr.mClass, profilerInfo, app.instr.mArguments, app.instr.mWatcher, app.instr.mUiAutomationConnection, testMode, mBinderTransactionTrackingEnabled, enableTrackAllocation, isRestrictedBackupMode || !normalMode, app.persistent, new Configuration(getGlobalConfiguration()), app.compat, getCommonServicesLocked(app.isolated), mCoreSettingsObserver.getCoreSettingsLocked(), buildSerial); } else { 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); } // See if the top visible activity is waiting to run in this process... if (normalMode) { try { if (mStackSupervisor.attachApplicationLocked(app)) { didSomething = true; } } catch (Exception e) { Slog.wtf(TAG, "Exception thrown launching activities in " + app, e); badApp = true; } } // Find any services that should be running in this process... if (!badApp) { try { didSomething |= mServices.attachApplicationLocked(app, processName); checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked"); } catch (Exception e) { Slog.wtf(TAG, "Exception thrown starting services in " + app, e); badApp = true; } } }
- 接着看看thread.bindApplication方法源代码,在ActivityThread类中
- 该bindApplication方法的实质是通过向ActivityThread的消息队列发送BIND_APPLICATION消息
- 消息的处理调用handleBindApplication方法,handleBindApplication方法比较重要的是会调用如下方法mInstrumentation.callApplicationOnCreate(app),callApplicationOnCreate即调用应用程序Application的onCreate()方法,说明Application的onCreate()方法会比所有activity的onCreate()方法先调用。
public final void bindApplication(String processName, ApplicationInfo appInfo, List<ProviderInfo> providers, ComponentName instrumentationName, ProfilerInfo profilerInfo, Bundle instrumentationArgs, IInstrumentationWatcher instrumentationWatcher, IUiAutomationConnection instrumentationUiConnection, int debugMode, boolean enableBinderTracking, boolean trackAllocation, boolean isRestrictedBackupMode, boolean persistent, Configuration config, CompatibilityInfo compatInfo, Map services, Bundle coreSettings, String buildSerial) { if (services != null) { // Setup the service cache in the ServiceManager ServiceManager.initServiceCache(services); } setCoreSettings(coreSettings); AppBindData data = new AppBindData(); //省略部分代码 sendMessage(H.BIND_APPLICATION, data); } //通过BIND_APPLICATION这个常量,找到接收消息的方法 //在ActivityThread类,找到handleBindApplication方法 try { mInstrumentation.callApplicationOnCreate(app); } catch (Exception e) { if (!mInstrumentation.onException(app, e)) { throw new RuntimeException( "Unable to create application " + app.getClass().getName() + ": " + e.toString(), e); } }
- 接着看看mStackSupervisor.attachApplicationLocked(app)这里面做了什么
- mStackSupervisor为ActivityManagerService的成员变量,类型为ActivityStackSupervisor。
- 从注释可以看出,mStackSupervisor为Activity堆栈管理辅助类实例。ActivityStackSupervisor的attachApplicationLocked()方法的调用了realStartActivityLocked()方法,在realStartActivityLocked()方法中,会调用scheduleLaunchActivity()方法:
- 这里面代码比较复杂,只是摘取部分代码
final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app, boolean andResume, boolean checkConfig) throws RemoteException { //... try { //... app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken, System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration), r.compat, r.icicle, results, newIntents, !andResume, mService.isNextTransitionForward(), profileFile, profileFd, profileAutoStop); //... } catch (RemoteException e) { //... } //... return true; }
2.2 ActivityThread类中scheduleCreateService()
- 然后看看ActivityThread.scheduleCreateService()
- 调用子类的 scheduleCreateService 方法,即最终调用 ApplicationThreadNative 的子类 ApplicationThread 的 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; sendMessage(H.CREATE_SERVICE, s); }
- 通过 Handler 发送 Message 来处理该操作,并进入到 H 的 handleMessage 方法中,其识别码为 CREATE_SERVICE。
- H.handleMessage()
private class H extends Handler { public void handleMessage(Message msg) { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceCreate"); //这里调用 handleCreateService 方法 handleCreateService((CreateServiceData)msg.obj); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } }
- 然后接着往下看ApplicationThread.handleCreateService()
- 处通过类加载器 ClassLoader 来加载 Service 对象
- 这里先创建一个 ContextImpl 对象,每个 Activity 和 Service 都有一个 Context 对象。
private void handleCreateService(CreateServiceData data) { Service service = null; try { //(1)通过类加载器来加载 Service 对象 java.lang.ClassLoader cl = packageInfo.getClassLoader(); service = (Service) cl.loadClass(data.info.name).newInstance(); } catch (Exception e) { //...... } //(2)这里创建 ContextImpl 对象 ContextImpl context = ContextImpl.createAppContext(this, packageInfo); context.setOuterContext(service); Application app = packageInfo.makeApplication(false, mInstrumentation); service.attach(context, this, data.info.name, data.token, app,ActivityManagerNative.getDefault()); //(3)这里调用 Service 的 onCreate 方法 service.onCreate(); mServices.put(data.token, service); }
03.bindService源码分析
3.1 绑定一个服务
- 代码如下所示
private void test(){ Intent intent = new Intent(this, XXXService.class); // bindService 的具体实现在 ContextImpl // BIND_AUTO_CREATE 参数具体使用的代码 ActivityServices bindService(intent, conn, BIND_AUTO_CREATE); } private ServiceConnection conn = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { // 绑定成功 ... } @Override public void onServiceDisconnected(ComponentName name) { // 绑定结束 ... } }
3.2 ContextImpl类中bindService()
- 代码如下所示
@Override public boolean bindService(Intent service, ServiceConnection conn, int flags) { // mMainThread.getHandler(),传入的 handle 是主线程的 Handle return bindServiceCommon(service, conn, flags, mMainThread.getHandler(), Process.myUserHandle()); } private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, Handler handler, UserHandle user) { IServiceConnection sd; //... if (mPackageInfo != null) { // 1,将传入的 ServiceConnection 转化为 IServiceConnection 返回 // mPackgeInfo 是 LoadedApk sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags); } validateServiceIntent(service); try { IBinder token = getActivityToken(); ... // 2,Binder 调用 AMS 的 bindService 方法,下面具体分析 int res = ActivityManagerNative.getDefault().bindService( mMainThread.getApplicationThread(), getActivityToken(), service, service.resolveTypeIfNeeded(getContentResolver()), sd, flags, getOpPackageName(), user.getIdentifier()); return res != 0; } //... }
- 接着看看getServiceDispatcher这个方法
public final IServiceConnection getServiceDispatcher(ServiceConnection c, Context context, Handler handler, int flags) { synchronized (mServices) { LoadedApk.ServiceDispatcher sd = null; // private final ArrayMap<Context, // ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>> mServices // 根据当前的 Context 获取 ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context); if (map != null) { // 如果存在,尝试根据当前的 ServiceConnection 获取 ServiceDispatcher sd = map.get(c); } if (sd == null) { // 如果与 ServiceConnection 对应的 ServiceDispatcher 不存在,创建一个保存了当前 // ServiceConnection 的 ServiceDispatcher 对象, // 并将之前传入的主线的 Handle 保存,同时创建一个 InnerConnection 对象保存 sd = new ServiceDispatcher(c, context, handler, flags); if (map == null) { map = new ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>(); mServices.put(context, map); } // 将该 ServiceConnection 与 ServiceDispatcher 关系保存 map.put(c, sd); } else { // 如果最开始就获取到 ServiceDispatcher,比如多次 bindService, // 就会调用 ServiceDispatcher 的 validate 判断此次 bindService 是否合法 // validate 的判断逻辑比较简单: // 1.判断当前的 context 是否和之前 bindService 的一样 // 2.判断当前 handler 是否是主线程的 handle // 以上两个条件都满足的情况下正常执行,反之抛出相应的异常 sd.validate(context, handler); } return sd.getIServiceConnection(); } }
- 接着找到ActivityManagerService.bindService()类
- 可以看到调用 ActiveServices 的 bindServiceLocked 方法,返回是int。注意这里用到了synchronized关键字,避免多次绑定
public int bindService(IApplicationThread caller, IBinder token, Intent service, String resolvedType, IServiceConnection connection, int flags, String callingPackage, int userId) throws TransactionTooLargeException { //... synchronized(this) { // 调用 ActiveServices 的 bindServiceLocked 方法 return mServices.bindServiceLocked(caller, token, service, resolvedType, connection, flags, callingPackage, userId); } }
- 接着又来看看mServices.bindServiceLocked里面的代码
- 大概流程是:ActiveServices.bindServiceLocked() -> bringUpServiceLocked() -> realStartServiceLocked()
private final void realStartServiceLocked(ServiceRecord r, ProcessRecord app, boolean execInFg) throws RemoteException { //... try { //... // 第一步,调用 ApplicationThread 的 scheduleCreateService 方法, // 之后会实例化 Service 并调用 Service 的 onCreate 方法,这里的过程跟上面 startService 中一样。 // 不会调用 onStartCommand app.thread.scheduleCreateService(r, r.serviceInfo, mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo), app.repProcState); } //... // 第二步,调用 requestServiceBindingLocked requestServiceBindingLocked(r, execInFg); updateServiceClientActivitiesLocked(app, null, true); // 第三步 // If the service is in the started state, and there are no // pending arguments, then fake up one so its onStartCommand() will // be called. if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) { r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(), null, null)); } // StartItem 的 taskRemoved 如果是 false 的话, // 调用下面方法会调用 Service 的 onStartCommand sendServiceArgsLocked(r, execInFg, true); //... } private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i, boolean execInFg, boolean rebind) throws TransactionTooLargeException { //... if ((!i.requested || rebind) && i.apps.size() > 0) { try { //... // 调用 ApplicationThread 的 scheduleBindService 方法 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind, r.app.repProcState); } //... } //... return true; }
- 最后看看这个方法ApplicationThread.scheduleBindService()
- 调用 ApplicationThread 的 scheduleBindService,scheduleBindService 通过 mH 发送一个 H.BIND_SERVICE 消息,mH 收到该消息调用 handleBindService(BindServiceData data)。
private void handleBindService(BindServiceData data) { // 根据 token 获取 Service token 具体分析 Service s = mServices.get(data.token); if (s != null) { try { // rebind 具体分析 if (!data.rebind) { // 调用 Service 的 onBind,返回给客户端调用的 Binder IBinder binder = s.onBind(data.intent); // 调用 AMS 的 publishService,进而通知客户端连接成功 ActivityManagerNative.getDefault() .publishService(data.token, data.intent, binder); } else { s.onRebind(data.intent); ActivityManagerNative.getDefault() .serviceDoneExecuting(data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0); } ensureJitEnabled(); } ... } }