Service基础知识 Android Study Plan II - Service
Service工作过程 Service分为两种工作状态,一种是启动状态
,主要用于执行后台计算;另一种是绑定状态
,主要用于其他组件和Service的交互。
Service的这两种状态是可以共存的,即Service既可以处于启动状态也可以同时处于绑定状态。
1 2 3 4 5 6 7 Intent intent= new Intent(this ,MyService.class ) ; startService(intent); Intent intent= new Intent(this ,MyService.class ) ; bindService(intent,mServiceConnection,BIND_AUTO_CREATE);
Service启动过程 - startService Service的启动过程从ContextWrapper.startService()
开始
1 2 3 4 5 6 Context mBase; @Override public ComponentName startService (Intent service) { return mBase.startService(service); }
在Activity启动的时候performLaunActivity
时,会创建上下文对象Context
,然后在Activity.attach()
调用了attachBaseContext()
将得到的contenxt进行赋值。最终操作的就是ContextImpl
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 @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 ) { ... } return cn; } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } }
ActivityManager.getService()
在Activity启动过程中有介绍它是得到IActiivtyManager
实际就是指向AMS
的一个Binder对象,调用到的就是AMS.startService()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 @Override public ComponentName startService (IApplicationThread caller, Intent service, String resolvedType, boolean requireForeground, String callingPackage, int userId) throws TransactionTooLargeException { enforceNotIsolatedCaller("startService" ); if (service != null && service.hasFileDescriptors() == true ) { throw new IllegalArgumentException("File descriptors passed in Intent" ); } if (callingPackage == null ) { throw new IllegalArgumentException("callingPackage cannot be null" ); } if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground); synchronized (this ) { final int callingPid = Binder.getCallingPid(); final int callingUid = Binder.getCallingUid(); final long origId = Binder.clearCallingIdentity(); ComponentName res; try { res = mServices.startServiceLocked(caller, service, resolvedType, callingPid, callingUid, requireForeground, callingPackage, userId); } finally { Binder.restoreCallingIdentity(origId); } return res; } }
mServices
的类型是ActiveServices
.ActiveServices
是一个辅助AMS
进行Service管理的类,其中包括Service的启动,绑定和停止等功能。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 ComponentName startServiceLocked (IApplicationThread caller, Intent service, String resolvedType, int callingPid, int callingUid, boolean fgRequired, String callingPackage, final int userId) throws TransactionTooLargeException { ... ServiceLookupResult res = retrieveServiceLocked(service, resolvedType, callingPackage, callingPid, callingUid, userId, true , callerFg, false ); if (res == null ) { return null ; } if (res.record == null ) { return new ComponentName("!" , res.permission != null ? res.permission : "private to package" ); } ServiceRecord r = res.record; ... ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting); }
ServiceRecord
描述的是一个Service记录,一直贯穿着整个Service的启动过程。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 ComponentName startServiceInnerLocked (ServiceMap smap, Intent service, ServiceRecord r, boolean callerFg, boolean addToStarting) throws TransactionTooLargeException { ... String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false , false ); if (error != null ) { return new ComponentName("!!" , error); } ... return r.name; }private String bringUpServiceLocked (ServiceRecord r, int intentFlags, boolean execInFg, boolean whileRestarting, boolean permissionsReviewRequired) throws TransactionTooLargeException { ... final String procName = r.processName; String hostingType = "service" ; ProcessRecord app; 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); realStartServiceLocked(r, app, execInFg); return null ; } catch (TransactionTooLargeException e) { throw e; } catch (RemoteException e) { Slog.w(TAG, "Exception when starting service " + r.shortName, e); } } } else { app = r.isolatedProc; if (WebViewZygote.isMultiprocessEnabled() && r.serviceInfo.packageName.equals(WebViewZygote.getPackageName())) { hostingType = "webview_service" ; } } if (app == null && !permissionsReviewRequired) { if ((app=mAm.startProcessLocked(procName, r.appInfo, true , intentFlags, hostingType, 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); bringDownServiceLocked(r); return msg; } if (isolated) { r.isolatedProc = app; } } ... }
在bringUpServiceLocked()
中,优先获取Service需要的运行进程--通过android:process设置
,然后去判断当前进程中是否存在符合要求的
不存在,调用AMS.startProcessLocked()
去新建对应应用进程,这个函数在Activity启动过程中有讲解
存在,直接调用realStartServiceLocked()
去启动Service,命名方法类似Activity启动过程中的realStartActivityLocked()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 private final void realStartServiceLocked (ServiceRecord r, ProcessRecord app, boolean execInFg) throws RemoteException { ... boolean created = false ; try { ... app.thread.scheduleCreateService(r, r.serviceInfo, mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo), app.repProcState); r.postNotification(); created = true ; } catch (DeadObjectException e) { Slog.w(TAG, "Application dead when creating service " + r); mAm.appDiedLocked(app); throw e; } finally { if (!created) { final boolean inDestroying = mDestroyingServices.contains(r); serviceDoneExecutingLocked(r, inDestroying, inDestroying); if (newService) { app.services.remove(r); r.app = null ; } if (!inDestroying) { scheduleServiceRestartLocked(r, false ); } } } ... if (r.startRequested && r.callStart && r.pendingStarts.size() == 0 ) { r.pendingStarts.add(new ServiceRecord.StartItem(r, false , r.makeNextStartId(), null , null , 0 )); } sendServiceArgsLocked(r, execInFg, true ); }private final void sendServiceArgsLocked (ServiceRecord r, boolean execInFg, boolean oomAdjusted) throws TransactionTooLargeException { ... r.app.thread.scheduleServiceArgs(r, slice); ... }
app.thread
是IApplicationThread
类型的,实际上是一个Binder对象,它的实现是ApplicationThread
,用于和ActivityThread
进行通信。
1 2 3 4 5 6 7 8 9 10 11 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); }
这里与Activity启动过程
是一致的,通过ActivityThread.H
这个Handler对象发送消息,切换到主线程去处理消息。这个发送的是CREATE_SERVICE
,最后调用到了ActivityThread.handleCreateService()
去启动Service
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 final ArrayMap<IBinder, Service> mServices = new ArrayMap<>(); private void handleCreateService (CreateServiceData data) { unscheduleGcIdler(); LoadedApk packageInfo = getPackageInfoNoCheck( data.info.applicationInfo, data.compatInfo); Service service = null ; try { 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 { if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name); 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, ActivityManager.getService()); service.onCreate(); mServices.put(data.token, service); try { ActivityManager.getService().serviceDoneExecuting( data.token, SERVICE_DONE_EXECUTING_ANON, 0 , 0 ); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } catch (Exception e) { if (!mInstrumentation.onException(service, e)) { throw new RuntimeException( "Unable to create service " + data.info.name + ": " + e.toString(), e); } } }
handleCreateService()
执行了以下的几件事:
通过类加载器创建Service
实例,Actiivty启动过程是利用了 Instrumention.newActivity() 执行相同创建实例
makeApplication()
创建Application
对象并调用其onCreate
创建ContextImpl
对象并调用Service.attach()
建立关系
最后调用Service.onCreate()
开始创建过程,并存储至ArrayMap<IBinder,Service>
中,在下一节会介绍这里存储数据的作用
调用onCreate()
之后,Service也已经启动了。
{% fullimage /images/Service启动过程.png,Service启动过程,Service启动过程%}
Service绑定过程 - bindService 和Service的启动过程一样,Service的绑定过程也是从ContextWrapper
开始
1 2 3 4 5 6 @Override public boolean bindService (Intent service, ServiceConnection conn, int flags) { return mBase.bindService(service, conn, flags); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 @Override public boolean bindService (Intent service, ServiceConnection conn, int flags) { warnIfCallingFromSystemProcess(); 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 (conn == null ) { throw new IllegalArgumentException("connection is null" ); } if (mPackageInfo != null ) { sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags); } else { throw new RuntimeException("Not supported in system context" ); } validateServiceIntent(service); try { ... service.prepareToLeaveProcess(this ); int res = ActivityManager.getService().bindService( mMainThread.getApplicationThread(), getActivityToken(), service, service.resolveTypeIfNeeded(getContentResolver()), sd, flags, getOpPackageName(), user.getIdentifier()); if (res < 0 ) { throw new SecurityException( "Not allowed to bind to service " + service); } return res != 0 ; } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } }
在bindServiceCommon()
主要做了两件事情:
getServiceDispatcher()
将传进来的ServiceConnection
转化成IServiceConnection
,通过Binder对象进行通信。使得Service的绑定支持跨进程调用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 public final IServiceConnection getServiceDispatcher (ServiceConnection c, Context context, Handler handler, int flags) { synchronized (mServices) { LoadedApk.ServiceDispatcher sd = null ; ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context); if (map != null ) { if (DEBUG) Slog.d(TAG, "Returning existing dispatcher " + sd + " for conn " + c); sd = map.get(c); } if (sd == null ) { sd = new ServiceDispatcher(c, context, handler, flags); if (DEBUG) Slog.d(TAG, "Creating new dispatcher " + sd + " for conn " + c); if (map == null ) { map = new ArrayMap<>(); mServices.put(context, map); } map.put(c, sd); } else { sd.validate(context, handler); } return sd.getIServiceConnection(); } }
mServices
存储了一个应用当前活动的ServiceConnection和ServiceDispatcher
的映射关系。ServiceDispatcher
的作用是连接ServiceConnection和IServiceConnection。
bindService()
开始Service的绑定流程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public int bindService (IApplicationThread caller, IBinder token, Intent service, String resolvedType, IServiceConnection connection, int flags, String callingPackage, int userId) throws TransactionTooLargeException { enforceNotIsolatedCaller("bindService" ); if (service != null && service.hasFileDescriptors() == true ) { throw new IllegalArgumentException("File descriptors passed in Intent" ); } if (callingPackage == null ) { throw new IllegalArgumentException("callingPackage cannot be null" ); } synchronized (this ) { return mServices.bindServiceLocked(caller, token, service, resolvedType, connection, flags, callingPackage, userId); } }
存储好对应的ServiceConnection
和ServiceDispatcher
映射的关系,之后开始继续绑定流程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 int bindServiceLocked (IApplicationThread caller, IBinder token, Intent service, String resolvedType, final IServiceConnection connection, int flags, String callingPackage, final int userId) throws TransactionTooLargeException { final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller); if (callerApp == null ) { throw new SecurityException( "Unable to find app for caller " + caller + " (pid=" + Binder.getCallingPid() + ") when binding service " + service); } ActivityRecord activity = null ; if (token != null ) { activity = ActivityRecord.isInStackLocked(token); if (activity == null ) { Slog.w(TAG, "Binding with unknown activity: " + token); return 0 ; } } ServiceRecord s = res.record; if (mAm.mPermissionReviewRequired) { if (mAm.getPackageManagerInternalLocked().isPermissionsReviewRequired( s.packageName, s.userId)) { RemoteCallback callback = new RemoteCallback( new RemoteCallback.OnResultListener() { @Override public void onResult (Bundle result) { synchronized (mAm) { final long identity = Binder.clearCallingIdentity(); try { ... if (...) { try { bringUpServiceLocked(...); } catch (RemoteException e) { } } else { ... } } finally { ... } } } }); final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS); intent.putExtra(Intent.EXTRA_REMOTE_CALLBACK, callback); mAm.mHandler.post(new Runnable() { @Override public void run () { mAm.mContext.startActivityAsUser(intent, new UserHandle(userId)); } }); } } try { if ((flags&Context.BIND_AUTO_CREATE) != 0 ) { s.lastActivity = SystemClock.uptimeMillis(); if (bringUpServiceLocked(s, service.getFlags(), callerFg, false , permissionsReviewRequired) != null ) { return 0 ; } } if (s.app != null && b.intent.received) { try { c.conn.connected(s.name, b.intent.binder, false ); } catch (Exception e) { ... } if (b.intent.apps.size() == 1 && b.intent.doRebind) { requestServiceBindingLocked(s, b.intent, callerFg, true ); } ... } else if (!b.intent.requested) { requestServiceBindingLocked(s, b.intent, callerFg, false ); } ... } finally { Binder.restoreCallingIdentity(origId); } return 1 ; }
介绍几个与Service有关的对象类型:
ServiceRecord:描述一个Service
ProcessREcord:描述一个进程的信息
ConnectionRecord:描述应用程序进程和Service建立的一次通信。
AppBindRecord:维护Srvice与应用程序进程之间的关联。
IntentBindRecord:描述绑定Service的Intent
bindServiceLocked()
内部会通过bringUpServiceLocked()
自动启动Service。然后向下走启动Service流程
。
还会多调用一个requestServiceBindingLocked()
请求绑定过程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 private final boolean requestServiceBindingLocked (ServiceRecord r, IntentBindRecord i, boolean execInFg, boolean rebind) throws TransactionTooLargeException { if (r.app == null || r.app.thread == null ) { return false ; } if (DEBUG_SERVICE) Slog.d(TAG_SERVICE, "requestBind " + i + ": requested=" + i.requested + " rebind=" + rebind); if ((!i.requested || rebind) && i.apps.size() > 0 ) { try { bumpServiceExecutingLocked(r, execInFg, "bind" ); r.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE); r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind, r.app.repProcState); if (!rebind) { i.requested = true ; } i.hasBound = true ; i.doRebind = false ; } catch (... ) { ... } } return true ; }
app.thread
把逻辑切换到了 ActivityThread
中了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 public final void scheduleBindService (IBinder token, Intent intent, boolean rebind, int processState) { updateProcessState(processState, false ); BindServiceData s = new BindServiceData(); s.token = token; s.intent = intent; s.rebind = rebind; if (DEBUG_SERVICE) Slog.v(TAG, "scheduleBindService token=" + token + " intent=" + intent + " uid=" + Binder.getCallingUid() + " pid=" + Binder.getCallingPid()); sendMessage(H.BIND_SERVICE, s); }private void handleBindService (BindServiceData data) { Service s = mServices.get(data.token); if (DEBUG_SERVICE) Slog.v(TAG, "handleBindService s=" + s + " rebind=" + data.rebind); if (s != null ) { try { data.intent.setExtrasClassLoader(s.getClassLoader()); data.intent.prepareToEnterProcess(); try { if (!data.rebind) { IBinder binder = s.onBind(data.intent); ActivityManager.getService().publishService( data.token, data.intent, binder); } else { s.onRebind(data.intent); ActivityManager.getService().serviceDoneExecuting( data.token, SERVICE_DONE_EXECUTING_ANON, 0 , 0 ); } ensureJitEnabled(); } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); } } catch (Exception e) { if (!mInstrumentation.onException(s, e)) { throw new RuntimeException( "Unable to bind to service " + s + " with " + data.intent + ": " + e.toString(), e); } } } }
Service.onRebind()
执行条件为:使用Service的流程是,先startService()
然后bindService()
,在Activity退出的时候,Service并不会停止,再进入Activity重新进行bindService()
,会触发onRebind()
方法。但是先前Activity退出时调用的onUnbind()
返回为true
,直接写死返回结果。
当多次绑定同一个Service时,onBind()
只会执行一次,除非Service被终止。
Service绑定通知 发现Service未绑定时,就会调用到onBind()
,Service就处于绑定状态,但是客户端无法感知到Service已经连接成功,所以需要AMS
进行通知。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 public void publishService (IBinder token, Intent intent, IBinder service) { if (intent != null && intent.hasFileDescriptors() == true ) { throw new IllegalArgumentException("File descriptors passed in Intent" ); } synchronized (this ) { if (!(token instanceof ServiceRecord)) { throw new IllegalArgumentException("Invalid service token" ); } mServices.publishServiceLocked((ServiceRecord)token, intent, service); } }
mServices
就是ActiveServices
对象,调用其内部的publishServiceLocked()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 void publishServiceLocked (ServiceRecord r, Intent intent, IBinder service) { final long origId = Binder.clearCallingIdentity(); try { ... for (int conni=r.connections.size()-1 ; conni>=0 ; conni--) { ArrayList<ConnectionRecord> clist = r.connections.valueAt(conni); for (int i=0 ; i<clist.size(); i++) { ConnectionRecord c = clist.get(i); try { c.conn.connected(r.name, service, false ); } catch (Exception e) { Slog.w(TAG, "Failure sending service " + r.name + " to connection " + c.conn.asBinder() + " (in " + c.binding.client.processName + ")" , e); } } } } serviceDoneExecutingLocked(r, mDestroyingServices.contains(r), false ); } } finally { Binder.restoreCallingIdentity(origId); } }
c.conn
指向IServiceConnection
,他是ServiceConnection
在本地的代理对象,用于解决当前应用程序进程和Service跨进程通信的问题。
他的具体实现为ServiceDispatcher.InnerConnection
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 static final class ServiceDispatcher { ... private static class InnerConnection extends IServiceConnection .Stub { final WeakReference<LoadedApk.ServiceDispatcher> mDispatcher; InnerConnection(LoadedApk.ServiceDispatcher sd) { mDispatcher = new WeakReference<LoadedApk.ServiceDispatcher>(sd); } public void connected (ComponentName name, IBinder service, boolean dead) throws RemoteException { LoadedApk.ServiceDispatcher sd = mDispatcher.get(); if (sd != null ) { sd.connected(name, service, dead); } } } public void connected (ComponentName name, IBinder service, boolean dead) { if (mActivityThread != null ) { mActivityThread.post(new RunConnection(name, service, 0 , dead)); } else { doConnected(name, service, dead); } } ... }
mActivityThread
是一个Handler对象,指向的就是ActivityThread.H
。因此可以通过调用post()
直接发送RunConnection
对象的内容运行在主线程中。mActivityThread不可能为空。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 private final class RunConnection implements Runnable { RunConnection(ComponentName name, IBinder service, int command, boolean dead) { mName = name; mService = service; mCommand = command; mDead = dead; } public void run () { if (mCommand == 0 ) { doConnected(mName, mService, mDead); } else if (mCommand == 1 ) { doDeath(mName, mService); } } final ComponentName mName; final IBinder mService; final int mCommand; final boolean mDead; }
调用了RunConnection
实际上还是调用了doConnected()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ServiceConnection mConnection;public void doConnected (ComponentName name, IBinder service, boolean dead) { ServiceDispatcher.ConnectionInfo old; ServiceDispatcher.ConnectionInfo info; synchronized (this ) { ... if (old != null ) { mConnection.onServiceDisconnected(name); } if (dead) { mConnection.onBindingDied(name); } if (service != null ) { mConnection.onServiceConnected(name, service); } }
1 2 3 4 5 6 7 8 9 10 11 12 private ServiceConnection mConnection = new ServiceConnection() { @Override public void onServiceConnected (ComponentName name, IBinder service) { } @Override public void onServiceDisconnected (ComponentName name) { } };
Service解绑过程 - unbindService() Service的解绑过程也是从ContextWrapper
开始
1 2 3 4 @Override public void unbindService (ServiceConnection conn) { mBase.unbindService(conn); }
实际调用的是ContextImpl.unbindService()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 @Override public void unbindService (ServiceConnection conn) { if (conn == null ) { throw new IllegalArgumentException("connection is null" ); } if (mPackageInfo != null ) { IServiceConnection sd = mPackageInfo.forgetServiceDispatcher( getOuterContext(), conn); try { ActivityManager.getService().unbindService(sd); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } else { throw new RuntimeException("Not supported in system context" ); } }
这里主要分为两部分:
调用到ActiveServices.unbindServiceLocked()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 boolean unbindServiceLocked (IServiceConnection connection) { IBinder binder = connection.asBinder(); if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "unbindService: conn=" + binder); ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder); if (clist == null ) { Slog.w(TAG, "Unbind failed: could not find connection for " + connection.asBinder()); return false ; } final long origId = Binder.clearCallingIdentity(); try { while (clist.size() > 0 ) { ConnectionRecord r = clist.get(0 ); removeConnectionLocked(r, null , null ); ... } mAm.updateOomAdjLocked(); } finally { Binder.restoreCallingIdentity(origId); } return true ; } void removeConnectionLocked ( ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) { IBinder binder = c.conn.asBinder(); AppBindRecord b = c.binding; ServiceRecord s = b.service; ArrayList<ConnectionRecord> clist = s.connections.get(binder); if (clist != null ) { clist.remove(c); if (clist.size() == 0 ) { s.connections.remove(binder); } } b.connections.remove(c); ... if (!c.serviceDead) { if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Disconnecting binding " + b.intent + ": shouldUnbind=" + b.intent.hasBound); if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0 && b.intent.hasBound) { try { bumpServiceExecutingLocked(s, false , "unbind" ); if (b.client != s.app && (c.flags&Context.BIND_WAIVE_PRIORITY) == 0 && s.app.setProcState <= ActivityManager.PROCESS_STATE_RECEIVER) { mAm.updateLruProcessLocked(s.app, false , null ); } mAm.updateOomAdjLocked(s.app, true ); b.intent.hasBound = false ; b.intent.doRebind = false ; s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent()); } catch (Exception e) { Slog.w(TAG, "Exception when unbinding service " + s.shortName, e); serviceProcessGoneLocked(s); } } ... if ((c.flags&Context.BIND_AUTO_CREATE) != 0 ) { boolean hasAutoCreate = s.hasAutoCreateConnections(); if (!hasAutoCreate) { if (s.tracker != null ) { s.tracker.setBound(false , mAm.mProcessStats.getMemFactorLocked(), SystemClock.uptimeMillis()); } } bringDownServiceIfNeededLocked(s, true , hasAutoCreate); } } }
又看到了熟悉的app.thread
就知道切换回到了ActivityThread
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 public final void scheduleUnbindService (IBinder token, Intent intent) { BindServiceData s = new BindServiceData(); s.token = token; s.intent = intent; sendMessage(H.UNBIND_SERVICE, s); }private void handleUnbindService (BindServiceData data) { Service s = mServices.get(data.token); if (s != null ) { try { data.intent.setExtrasClassLoader(s.getClassLoader()); data.intent.prepareToEnterProcess(); boolean doRebind = s.onUnbind(data.intent); try { if (doRebind) { ActivityManager.getService().unbindFinished( data.token, data.intent, doRebind); } else { ActivityManager.getService().serviceDoneExecuting( data.token, SERVICE_DONE_EXECUTING_ANON, 0 , 0 ); } } catch (RemoteException ex) { throw ex.rethrowFromSystemServer(); } } catch (Exception e) { ... } } }
当Service调用onUnbind()
之后,还需要做一件事情,如果是靠bindService()
并配置flag
为BIND_AUTO_CREATE
。那么后续还会执行到stopService()
中的流程,即会调用到Service.onDestroy()
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 void removeConnectionLocked ( //如果是利用 BIND_AUTO_CREATE的flag就会向下调用 if ((c.flags&Context.BIND_AUTO_CREATE) ! = 0 ) { boolean hasAutoCreate = s.hasAutoCreateConnections(); if (!hasAutoCreate) { if (s.tracker != null ) { s.tracker.setBound(false , mAm.mProcessStats.getMemFactorLocked(), SystemClock.uptimeMillis()); } } bringDownServiceIfNeededLocked(s, true , hasAutoCreate); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 private final void bringDownServiceIfNeededLocked (ServiceRecord r, boolean knowConn, boolean hasConn) { if (isServiceNeededLocked(r, knowConn, hasConn)) { return ; } if (mPendingServices.contains(r)) { return ; } bringDownServiceLocked(r); }private final boolean isServiceNeededLocked (ServiceRecord r, boolean knowConn, boolean hasConn) { if (r.startRequested) { return true ; } if (!knowConn) { hasConn = r.hasAutoCreateConnections(); } if (hasConn) { return true ; } return false ; }
Service停止过程 - stopService() 还是由ContextWrapper.stopService()
开始执行
1 2 3 4 @Override public boolean stopService (Intent name) { return mBase.stopService(name); }
向下执行到ContextImpl.stopService()
中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 @Override public boolean stopService (Intent service) { warnIfCallingFromSystemProcess(); return stopServiceCommon(service, mUser); }private boolean stopServiceCommon (Intent service, UserHandle user) { try { validateServiceIntent(service); service.prepareToLeaveProcess(this ); int res = ActivityManager.getService().stopService( mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(getContentResolver()), user.getIdentifier()); if (res < 0 ) { throw new SecurityException( "Not allowed to stop service " + service); } return res != 0 ; } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } }
ActivityManager.getService()
实际就是指向ActivityManagerService
的一个Binder对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 @Override public int stopService (IApplicationThread caller, Intent service, String resolvedType, int userId) { enforceNotIsolatedCaller("stopService" ); if (service != null && service.hasFileDescriptors() == true ) { throw new IllegalArgumentException("File descriptors passed in Intent" ); } synchronized (this ) { return mServices.stopServiceLocked(caller, service, resolvedType, userId); } }
mServices
是ActiveServices
的一个实际对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 int stopServiceLocked (IApplicationThread caller, Intent service, String resolvedType, int userId) { ... ServiceLookupResult r = retrieveServiceLocked(service, resolvedType, null , Binder.getCallingPid(), Binder.getCallingUid(), userId, false , false , false ); if (r != null ) { if (r.record != null ) { final long origId = Binder.clearCallingIdentity(); try { stopServiceLocked(r.record); } finally { Binder.restoreCallingIdentity(origId); } return 1 ; } return -1 ; } return 0 ; } private void stopServiceLocked (ServiceRecord service) { ... service.startRequested = false ; if (service.tracker != null ) { service.tracker.setStarted(false , mAm.mProcessStats.getMemFactorLocked(), SystemClock.uptimeMillis()); } service.callStart = false ; bringDownServiceIfNeededLocked(service, false , false ); } private final boolean isServiceNeededLocked (ServiceRecord r, boolean knowConn, boolean hasConn) { if (r.startRequested) { return true ; } if (!knowConn) { hasConn = r.hasAutoCreateConnections(); } if (hasConn) { return true ; } return false ; } private final void bringDownServiceIfNeededLocked (ServiceRecord r, boolean knowConn, boolean hasConn) { if (isServiceNeededLocked(r, knowConn, hasConn)) { return ; } if (mPendingServices.contains(r)) { return ; } bringDownServiceLocked(r); }
最后调用到了bringDownServiceLocked()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 private final void bringDownServiceLocked (ServiceRecord r) { ... if (r.app != null ) { synchronized (r.stats.getBatteryStats()) { r.stats.stopLaunchedLocked(); } r.app.services.remove(r); if (r.whitelistManager) { updateWhitelistManagerLocked(r.app); } if (r.app.thread != null ) { updateServiceForegroundLocked(r.app, false ); try { bumpServiceExecutingLocked(r, false , "destroy" ); mDestroyingServices.add(r); r.destroying = true ; mAm.updateOomAdjLocked(r.app, true ); r.app.thread.scheduleStopService(r); } catch (Exception e) { Slog.w(TAG, "Exception when destroying service " + r.shortName, e); serviceProcessGoneLocked(r); } } else { if (DEBUG_SERVICE) Slog.v( TAG_SERVICE, "Removed service that has no process: " + r); } } else { if (DEBUG_SERVICE) Slog.v( TAG_SERVICE, "Removed service that is not running: " + r); } ... }
app.thread
切换到ApplicaitonThread
继续执行流程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 public final void scheduleStopService (IBinder token) { sendMessage(H.STOP_SERVICE, token); }private void handleStopService (IBinder token) { Service s = mServices.remove(token); if (s != null ) { try { if (localLOGV) Slog.v(TAG, "Destroying service " + s); s.onDestroy(); s.detachAndCleanUp(); Context context = s.getBaseContext(); if (context instanceof ContextImpl) { final String who = s.getClassName(); ((ContextImpl) context).scheduleFinalCleanup(who, "Service" ); } QueuedWork.waitToFinish(); try { ActivityManager.getService().serviceDoneExecuting( token, SERVICE_DONE_EXECUTING_STOP, 0 , 0 ); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } catch (Exception e) { ... } } else { ... } }
最后执行到Service.onDestroy
完成停止流程。
拓展 为什么Activity退出时bindService()
的Service会一并销毁?
观察源码发现,bindService()
也会去启动Service,但为什么没有回调到onStartCommand()
?