可以通过调用Context的startService来启动Service,也可以通过Context的bindService来绑定Service
下面是Service的绑定过程
1.ContextWrapper.bindService
代码路径:/frameworks/base/core/java/android/content/ContextWrapper.java
(http://androidxref.com/8.0.0_r4/xref/frameworks/base/core/java/android/content/ContextWrapper.java)
675 @Override 676 public boolean bindService(Intent service, ServiceConnection conn, 677 int flags) { 678 return mBase.bindService(service, conn, flags); 679 }
用bindService方法来绑定Service,它的实现在ContextWrapper中
2.ContextImpl.bindService
代码路径:/frameworks/base/core/java/android/app/ContextImpl.java1537 @Override 1538 public boolean bindService(Intent service, ServiceConnection conn, 1539 int flags) { 1540 warnIfCallingFromSystemProcess(); 1541 return bindServiceCommon(service, conn, flags, mMainThread.getHandler(), 1542 Process.myUserHandle()); 1543 }
在bindService方法中,又return了bindServiceCommon方法
3.ContextImpl.bindServiceCommon
代码路径:/frameworks/base/core/java/android/app/ContextImpl.java
(http://androidxref.com/8.0.0_r4/xref/frameworks/base/core/java/android/app/ContextImpl.java)
1581 private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, Handler 1582 handler, UserHandle user) { 1583 // Keep this in sync with DevicePolicyManager.bindDeviceAdminServiceAsUser. 1584 IServiceConnection sd; 1585 if (conn == null) { 1586 throw new IllegalArgumentException("connection is null"); 1587 } 1588 if (mPackageInfo != null) { 1589 sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags); 1590 } else { 1591 throw new RuntimeException("Not supported in system context"); 1592 } 1593 validateServiceIntent(service); 1594 try { 1595 IBinder token = getActivityToken(); 1596 if (token == null && (flags&BIND_AUTO_CREATE) == 0 && mPackageInfo != null 1597 && mPackageInfo.getApplicationInfo().targetSdkVersion 1598 < android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) { 1599 flags |= BIND_WAIVE_PRIORITY; 1600 } 1601 service.prepareToLeaveProcess(this); 1602 int res = ActivityManager.getService().bindService( 1603 mMainThread.getApplicationThread(), getActivityToken(), service, 1604 service.resolveTypeIfNeeded(getContentResolver()), 1605 sd, flags, getOpPackageName(), user.getIdentifier()); 1606 if (res < 0) { 1607 throw new SecurityException( 1608 "Not allowed to bind to service " + service); 1609 } 1610 return res != 0; 1611 } catch (RemoteException e) { 1612 throw e.rethrowFromSystemServer(); 1613 } 1614 }
在bindServiceCommon方法中会在1602行调用ActivityManageService(AMS)的代理对象的bindService方法,最终会调用AMS的bindService方法
这里与Android 7.0代码的逻辑有些不同,Android 7.0是通过ActivityManagerNative的getDefault来获取AMS的代理对象,现在这个逻辑封装到了ActivityManager中而不是ActivityManagerNative中
4.ActivityManagerService.bindService
代码路径:/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
(http://androidxref.com/8.0.0_r4/xref/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java)
18275 public int bindService(IApplicationThread caller, IBinder token, Intent service, 18276 String resolvedType, IServiceConnection connection, int flags, String callingPackage, 18277 int userId) throws TransactionTooLargeException { 18278 enforceNotIsolatedCaller("bindService"); 18279 18280 // Refuse possible leaked file descriptors 18281 if (service != null && service.hasFileDescriptors() == true) { 18282 throw new IllegalArgumentException("File descriptors passed in Intent"); 18283 } 18284 18285 if (callingPackage == null) { 18286 throw new IllegalArgumentException("callingPackage cannot be null"); 18287 } 18288 18289 synchronized(this) { 18290 return mServices.bindServiceLocked(caller, token, service, 18291 resolvedType, connection, flags, callingPackage, userId); 18292 } 18293 }
在18290行bindService方法最后会调用ActiveServices类型的对象mServices的bindServiceLocked方法
5.ActiveServices.bindService
代码路径:/frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
(http://androidxref.com/8.0.0_r4/xref/frameworks/base/services/core/java/com/android/server/am/ActiveServices.java)
1228 int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service, 1229 String resolvedType, final IServiceConnection connection, int flags, 1230 String callingPackage, final int userId) throws TransactionTooLargeException { ......................................... 1435 1436 if ((flags&Context.BIND_AUTO_CREATE) != 0) { 1437 s.lastActivity = SystemClock.uptimeMillis(); 1438 if (bringUpServiceLocked(s, service.getFlags(), callerFg, false, 1439 permissionsReviewRequired) != null) { 1440 return 0; 1441 } 1442 } 1443 ........................................... 1461 1462 if (s.app != null && b.intent.received) { 1463 // Service is already running, so we can immediately 1464 // publish the connection. 1465 try { 1466 c.conn.connected(s.name, b.intent.binder, false); 1467 } catch (Exception e) { 1468 Slog.w(TAG, "Failure sending service " + s.shortName 1469 + " to connection " + c.conn.asBinder() 1470 + " (in " + c.binding.client.processName + ")", e); 1471 } 1472 1473 // If this is the first app connected back to this binding, 1474 // and the service had previously asked to be told when 1475 // rebound, then do so. 1476 if (b.intent.apps.size() == 1 && b.intent.doRebind) { 1477 requestServiceBindingLocked(s, b.intent, callerFg, true); 1478 } 1479 } else if (!b.intent.requested) { 1480 requestServiceBindingLocked(s, b.intent, callerFg, false); 1481 } 1482 1483 getServiceMapLocked(s.userId).ensureNotStartingBackgroundLocked(s); 1484 1485 } finally { 1486 Binder.restoreCallingIdentity(origId); 1487 } 1488 1489 return 1; 1490 }在1438行会bringUpServiceLocked方法,在bringUpServiceLocked方法中又会调用realStartServiceLocked方法,最终由ActivityThread来调用Service的onCreate方法启动Service
在1462行s.app != null 表示Service已经运行,其中s是ServiceRecord类型对象,app是ProcessRecord类型对象。b.intent.received表示当前应用程序进程的Client端已经接收到绑定Service时返回的Binder,这样应用程序进程的Client端就可以通过Binder来获取要绑定的Service的访问接口。
在1466行调用c.conn的connected方法,其中c.conn指的是IServiceConnection,它的具体实现为ServiceDispatcher.InnerConnection,其中ServiceDispatcher是LoadedApk的内部类,InnerConnection的connected方法内部会调用H的post方法向主线程发送消息,从而解决当前应用程序进程和Service跨进程通信的问题。
在1476行如果当前应用程序进程的Client端第一次与Service进行绑定的,并且Service已经调用过onUnBind方法,则需要调用 requestServiceBindingLocked。在1479行如果应用程序进程的Client端没有发送过绑定Service的请求,则会调用注释7的代码,注释7和注释5的代码区别就是最后一个参数rebind为false,表示不是重新绑定。
6.ActiveServices.requestServiceBindingLocked
代码路径:/frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
(http://androidxref.com/8.0.0_r4/xref/frameworks/base/services/core/java/com/android/server/am/ActiveServices.java)
1840 private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i, 1841 boolean execInFg, boolean rebind) throws TransactionTooLargeException { 1842 if (r.app == null || r.app.thread == null) { 1843 // If service is not currently running, can't yet bind. 1844 return false; 1845 } 1846 if (DEBUG_SERVICE) Slog.d(TAG_SERVICE, "requestBind " + i + ": requested=" + i.requested 1847 + " rebind=" + rebind); 1848 if ((!i.requested || rebind) && i.apps.size() > 0) { 1849 try { 1850 bumpServiceExecutingLocked(r, execInFg, "bind"); 1851 r.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE); 1852 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind, 1853 r.app.repProcState); 1854 if (!rebind) { 1855 i.requested = true; 1856 } 1857 i.hasBound = true; 1858 i.doRebind = false; 1859 } catch (TransactionTooLargeException e) { 1860 // Keep the executeNesting count accurate. 1861 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Crashed while binding " + r, e); 1862 final boolean inDestroying = mDestroyingServices.contains(r); 1863 serviceDoneExecutingLocked(r, inDestroying, inDestroying); 1864 throw e; 1865 } catch (RemoteException e) { 1866 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Crashed while binding " + r); 1867 // Keep the executeNesting count accurate. 1868 final boolean inDestroying = mDestroyingServices.contains(r); 1869 serviceDoneExecutingLocked(r, inDestroying, inDestroying); 1870 return false; 1871 } 1872 } 1873 return true; 1874 }
在1848行i.requested表示是否发送过绑定Service的请求,从前面的代码得知是没有发送过,因此,!i.requested为true。从前面的代码得知rebind值为false,那么(!i.requested || rebind)的值为true。
如果IntentBindRecord中的应用程序进程记录大于0,则会调用1852行的代码,r.app.thread的类型为IApplicationThread
7.ActivityThread.scheduleBindService
代码路径:/frameworks/base/core/java/android/app/ActivityThread.java
(http://androidxref.com/8.0.0_r4/xref/frameworks/base/core/java/android/app/ActivityThread.java)
852 public final void scheduleBindService(IBinder token, Intent intent, 853 boolean rebind, int processState) { 854 updateProcessState(processState, false); 855 BindServiceData s = new BindServiceData(); 856 s.token = token; 857 s.intent = intent; 858 s.rebind = rebind; 859 860 if (DEBUG_SERVICE) 861 Slog.v(TAG, "scheduleBindService token=" + token + " intent=" + intent + " uid=" 862 + Binder.getCallingUid() + " pid=" + Binder.getCallingPid()); 863 sendMessage(H.BIND_SERVICE, s); 864 }
首先将Service的信息封装成BindServiceData对象,需要注意的BindServiceData的成员变量rebind的值为false。接着将BindServiceData传入到sendMessage方法中。sendMessage向H发送消息。
8.ActivityThread.handleMessage
代码路径:/frameworks/base/core/java/android/app/ActivityThread.java
(http://androidxref.com/8.0.0_r4/xref/frameworks/base/core/java/android/app/ActivityThread.java)
1584 public void handleMessage(Message msg) { 1585 if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what)); 1586 switch (msg.what) { .............................................. 1686 case BIND_SERVICE: 1687 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind"); 1688 handleBindService((BindServiceData)msg.obj); 1689 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1690 break; 1691 case UNBIND_SERVICE: 1692 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceUnbind"); 1693 handleUnbindService((BindServiceData)msg.obj); 1694 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1695 break; ............................................. 1859 } 1860 Object obj = msg.obj; 1861 if (obj instanceof SomeArgs) { 1862 ((SomeArgs) obj).recycle(); 1863 } 1864 if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what)); 1865 }
在1686行H在接收到BIND_SERVICE类型消息时,会在handleMessage方法中会调用handleBindService方法
9.ActivityThread.handleBindService
代码路径:/frameworks/base/core/java/android/app/ActivityThread.java
(http://androidxref.com/8.0.0_r4/xref/frameworks/base/core/java/android/app/ActivityThread.java)
3421 private void handleBindService(BindServiceData data) { 3422 Service s = mServices.get(data.token); 3423 if (DEBUG_SERVICE) 3424 Slog.v(TAG, "handleBindService s=" + s + " rebind=" + data.rebind); 3425 if (s != null) { 3426 try { 3427 data.intent.setExtrasClassLoader(s.getClassLoader()); 3428 data.intent.prepareToEnterProcess(); 3429 try { 3430 if (!data.rebind) { 3431 IBinder binder = s.onBind(data.intent); 3432 ActivityManager.getService().publishService( 3433 data.token, data.intent, binder); 3434 } else { 3435 s.onRebind(data.intent); 3436 ActivityManager.getService().serviceDoneExecuting( 3437 data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0); 3438 } 3439 ensureJitEnabled(); 3440 } catch (RemoteException ex) { 3441 throw ex.rethrowFromSystemServer(); 3442 } 3443 } catch (Exception e) { 3444 if (!mInstrumentation.onException(s, e)) { 3445 throw new RuntimeException( 3446 "Unable to bind to service " + s 3447 + " with " + data.intent + ": " + e.toString(), e); 3448 } 3449 } 3450 } 3451 }
在3422行获取要绑定的Service 。
在3430行的BindServiceData的成员变量rebind的值为false,
这样会调用在3431行的代码来调用Service的onBind方法,这样Service处于绑定状态了。
如果rebind的值为true就会调用3435行的Service的onRebind方法.
在3432行,实际上是调用AMS的publishService方法。
9.ActivityThread.publishService
代码路径:/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
(http://androidxref.com/8.0.0_r4/xref/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java)
18301 public void publishService(IBinder token, Intent intent, IBinder service) { 18302 // Refuse possible leaked file descriptors 18303 if (intent != null && intent.hasFileDescriptors() == true) { 18304 throw new IllegalArgumentException("File descriptors passed in Intent"); 18305 } 18306 18307 synchronized(this) { 18308 if (!(token instanceof ServiceRecord)) { 18309 throw new IllegalArgumentException("Invalid service token"); 18310 } 18311 mServices.publishServiceLocked((ServiceRecord)token, intent, service); 18312 } 18313 }
publishService方法中,调用了ActiveServices类型的mServices对象的publishServiceLocked方法
10.ActiveServices.publishServiceLocked
代码路径:/frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
(http://androidxref.com/8.0.0_r4/xref/frameworks/base/services/core/java/com/android/server/am/ActiveServices.java)
1492 void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) { 1493 final long origId = Binder.clearCallingIdentity(); 1494 try { 1495 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "PUBLISHING " + r 1496 + " " + intent + ": " + service); 1497 if (r != null) { 1498 Intent.FilterComparison filter 1499 = new Intent.FilterComparison(intent); 1500 IntentBindRecord b = r.bindings.get(filter); 1501 if (b != null && !b.received) { 1502 b.binder = service; 1503 b.requested = true; 1504 b.received = true; 1505 for (int conni=r.connections.size()-1; conni>=0; conni--) { 1506 ArrayListclist = r.connections.valueAt(conni); 1507 for (int i=0; i if (!filter.equals(c.binding.intent.intent)) { 1510 if (DEBUG_SERVICE) Slog.v( 1511 TAG_SERVICE, "Not publishing to: " + c); 1512 if (DEBUG_SERVICE) Slog.v( 1513 TAG_SERVICE, "Bound intent: " + c.binding.intent.intent); 1514 if (DEBUG_SERVICE) Slog.v( 1515 TAG_SERVICE, "Published intent: " + intent); 1516 continue; 1517 } 1518 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Publishing to: " + c); 1519 try { 1520 c.conn.connected(r.name, service, false); 1521 } catch (Exception e) { 1522 Slog.w(TAG, "Failure sending service " + r.name + 1523 " to connection " + c.conn.asBinder() + 1524 " (in " + c.binding.client.processName + ")", e); 1525 } 1526 } 1527 } 1528 } 1529 1530 serviceDoneExecutingLocked(r, mDestroyingServices.contains(r), false); 1531 } 1532 } finally { 1533 Binder.restoreCallingIdentity(origId); 1534 } 1535 }
在1520行c.conn指的是IServiceConnection,它的具体实现为ServiceDispatcher.InnerConnection,其中ServiceDispatcher是LoadedApk的内部类。
11.LoadedApk.ServiceDispatcher.connected
代码路径:/frameworks/base/core/java/android/app/LoadedApk.java (http://androidxref.com/8.0.0_r4/xref/frameworks/base/core/java/android/app/LoadedApk.java)
471 static final class ServiceDispatcher { .......................................................... 1487 1488 private static class InnerConnection extends IServiceConnection.Stub { 1489 final WeakReferencemDispatcher; 1490 1491 InnerConnection(LoadedApk.ServiceDispatcher sd) { 1492 mDispatcher = new WeakReference (sd); 1493 } 1494 1495 public void connected(ComponentName name, IBinder service, boolean dead) 1496 throws RemoteException { 1497 LoadedApk.ServiceDispatcher sd = mDispatcher.get(); 1498 if (sd != null) { 1499 sd.connected(name, service, dead); 1500 } 1501 } 1502 }
..........................................................
1689 }1499行调用了ServiceDispatcher 类型的sd对象的connected方法
12.LoadedApk.connected
代码路径:/frameworks/base/core/java/android/app/LoadedApk.java (http://androidxref.com/8.0.0_r4/xref/frameworks/base/core/java/android/app/LoadedApk.java)
1568 public void connected(ComponentName name, IBinder service, boolean dead) {
1569 if (mActivityThread != null) {
1570 mActivityThread.post(new RunConnection(name, service, 0, dead));
1571 } else {
1572 doConnected(name, service, dead);
1573 }
1574 }
在1570行调用Handler类型的对象mActivityThread的post方法,mActivityThread实际上指向的是H。因此,通过调用H的post方法将RunConnection对象的内容运行在主线程中。
13.LoadedApk.RunConnection.run
代码路径:/frameworks/base/core/java/android/app/LoadedApk.java
(http://androidxref.com/8.0.0_r4/xref/frameworks/base/core/java/android/app/LoadedApk.java)
1653 private final class RunConnection implements Runnable { 1654 RunConnection(ComponentName name, IBinder service, int command, boolean dead) { 1655 mName = name; 1656 mService = service; 1657 mCommand = command; 1658 mDead = dead; 1659 } 1660 1661 public void run() { 1662 if (mCommand == 0) { 1663 doConnected(mName, mService, mDead); 1664 } else if (mCommand == 1) { 1665 doDeath(mName, mService); 1666 } 1667 } 1668 1669 final ComponentName mName; 1670 final IBinder mService; 1671 final int mCommand; 1672 final boolean mDead; 1673 }
1661行RunConnection的run方法中调用了doConnected方法
14.LoadedApk.doConnected
代码路径:/frameworks/base/core/java/android/app/LoadedApk.java (http://androidxref.com/8.0.0_r4/xref/frameworks/base/core/java/android/app/LoadedApk.java)
1584 public void doConnected(ComponentName name, IBinder service, boolean dead) { 1585 ServiceDispatcher.ConnectionInfo old; 1586 ServiceDispatcher.ConnectionInfo info; 1587 1588 synchronized (this) { 1589 if (mForgotten) { 1590 // We unbound before receiving the connection; ignore 1591 // any connection received. 1592 return; 1593 } 1594 old = mActiveConnections.get(name); 1595 if (old != null && old.binder == service) { 1596 // Huh, already have this one. Oh well! 1597 return; 1598 } 1599 1600 if (service != null) { 1601 // A new service is being connected... set it all up. 1602 info = new ConnectionInfo(); 1603 info.binder = service; 1604 info.deathMonitor = new DeathMonitor(name, service); 1605 try { 1606 service.linkToDeath(info.deathMonitor, 0); 1607 mActiveConnections.put(name, info); 1608 } catch (RemoteException e) { 1609 // This service was dead before we got it... just 1610 // don't do anything with it. 1611 mActiveConnections.remove(name); 1612 return; 1613 } 1614 1615 } else { 1616 // The named service is being disconnected... clean up. 1617 mActiveConnections.remove(name); 1618 } 1619 1620 if (old != null) { 1621 old.binder.unlinkToDeath(old.deathMonitor, 0); 1622 } 1623 } 1624 1625 // If there was an old service, it is now disconnected. 1626 if (old != null) { 1627 mConnection.onServiceDisconnected(name); 1628 } 1629 if (dead) { 1630 mConnection.onBindingDied(name); 1631 } 1632 // If there is a new service, it is now connected. 1633 if (service != null) { 1634 mConnection.onServiceConnected(name, service); 1635 } 1636 }1634行调用了ServiceConnection类型的对象mConnection的onServiceConnected方法,这样在客户端中实现了ServiceConnection接口的类的onServiceConnected方法就会被执行