梳理下bindService的相关流程
ContextImpl#bindService
1553 @Override
1554 public boolean bindService(Intent service, ServiceConnection conn,
1555 int flags) {
1556 warnIfCallingFromSystemProcess();
1557 return bindServiceCommon(service, conn, flags, mMainThread.getHandler(),
1558 Process.myUserHandle());
1559 }
ContextImpl#bindServiceCommon
1597 private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, Handler
1598 handler, UserHandle user) {
1599 // Keep this in sync with DevicePolicyManager.bindDeviceAdminServiceAsUser.
1600 IServiceConnection sd;
1601 if (conn == null) {
1602 throw new IllegalArgumentException("connection is null");
1603 }
1604 if (mPackageInfo != null) {
1605 sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);
//返回ServiceConnection对应的binder对象,这个在客户端也有保存,避免一个客户端重复生成binder对象(首次创建,本地保存)
1606 } else {
1607 throw new RuntimeException("Not supported in system context");
1608 }
1609 validateServiceIntent(service);
1610 try {
1611 IBinder token = getActivityToken();
1612 if (token == null && (flags&BIND_AUTO_CREATE) == 0 && mPackageInfo != null
1613 && mPackageInfo.getApplicationInfo().targetSdkVersion
1614 < android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
1615 flags |= BIND_WAIVE_PRIORITY;
1616 }
1617 service.prepareToLeaveProcess(this);
1618 int res = ActivityManager.getService().bindService(
1619 mMainThread.getApplicationThread(), getActivityToken(), service,
1620 service.resolveTypeIfNeeded(getContentResolver()),
1621 sd, flags, getOpPackageName(), user.getIdentifier());
1622 if (res < 0) {
1623 throw new SecurityException(
1624 "Not allowed to bind to service " + service);
1625 }
1626 return res != 0;
1627 } catch (RemoteException e) {
1628 throw e.rethrowFromSystemServer();
1629 }
1630 }
ContextImpl#getServiceDispatcher
返回客户端的ServiceConnection对象对应的binder对象
1580 public IServiceConnection getServiceDispatcher(ServiceConnection conn, Handler handler,
1581 int flags) {
1582 return mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);
1583 }
LoadedApk#getServiceDispatcher
LoadedApk: apk文件在内存中的展现
1414 public final IServiceConnection getServiceDispatcher(ServiceConnection c,
1415 Context context, Handler handler, int flags) {
1416 synchronized (mServices) {
1417 LoadedApk.ServiceDispatcher sd = null;
1418 ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context);
1419 if (map != null) {
1420 if (DEBUG) Slog.d(TAG, "Returning existing dispatcher " + sd + " for conn " + c);
1421 sd = map.get(c);
1422 }
1423 if (sd == null) {
1424 sd = new ServiceDispatcher(c, context, handler, flags);
//初始时,在本地创建需要创建ServiceConnection对应的ServiceDispatcher
1425 if (DEBUG) Slog.d(TAG, "Creating new dispatcher " + sd + " for conn " + c);
1426 if (map == null) {
1427 map = new ArrayMap<>();
//然后将ServiceDispatcher加入到mServices中
//前面分析Unbounded Service的结束流程时已经提到过
//Bounded Service结束时,ContextImpl中的scheduleFinalCleanup函数
//就会清理mServices中的信息
1428 mServices.put(context, map); //客户端本地保存与ServiceConnection对象相关的ServiceDispatcher对象
1429 }
1430 map.put(c, sd); //一个ServiceConnection对应一个ServiceDispatcher
1431 } else {
1432 sd.validate(context, handler);
1433 }
1434 return sd.getIServiceConnection(); //返回的是InnerConnection,为一个binder对象
//将这个binder对象传到AMS中,其包含着客户端ServiceDispatcher的弱引用,则通过这个对象可以调用客户端的相关函数(如onServiceConnected)
1435 }
1436 }
//见LoadedApk.ServiceDispatcher
1570 IServiceConnection getIServiceConnection() {
1571 return mIServiceConnection;
1572 }
1490 private final ServiceDispatcher.InnerConnection mIServiceConnection;
1506 private static class InnerConnection extends IServiceConnection.Stub
ActivityManagerService#bindService
18955
18956 public int bindService(IApplicationThread caller, IBinder token, Intent service,
18957 String resolvedType, IServiceConnection connection, int flags, String callingPackage,
18958 int userId) throws TransactionTooLargeException {
//token代表ActivityToken,如果是从Activity来bindService的,这个值不为null
//connection代表客户端的ServiceConnection对象在AMS中的binder对象
18959 enforceNotIsolatedCaller("bindService");
18960
18961 // Refuse possible leaked file descriptors
18962 if (service != null && service.hasFileDescriptors() == true) {
18963 throw new IllegalArgumentException("File descriptors passed in Intent");
18964 }
18971
18972 if (callingPackage == null) {
18973 throw new IllegalArgumentException("callingPackage cannot be null");
18974 }
18975
18976 synchronized(this) {
18977 return mServices.bindServiceLocked(caller, token, service,
18978 resolvedType, connection, flags, callingPackage, userId);
18979 }
18980 }
ActiveServices#bindServiceLocked
1286 int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,
1287 String resolvedType, final IServiceConnection connection, int flags,
1288 String callingPackage, final int userId) throws TransactionTooLargeException {
1289 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "bindService: " + service
1290 + " type=" + resolvedType + " conn=" + connection.asBinder()
1291 + " flags=0x" + Integer.toHexString(flags));
1292 final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller); //得到客户端(caller)的进程信息
1293 if (callerApp == null) {
1294 throw new SecurityException(
1295 "Unable to find app for caller " + caller
1296 + " (pid=" + Binder.getCallingPid()
1297 + ") when binding service " + service);
1298 }
1299
1306
1307 ActivityRecord activity = null;
1308 if (token != null) {
1309 activity = ActivityRecord.isInStackLocked(token); //如果是一个Activity绑定Service, 那么该Activity必须是有效的 //判断Activity是否存在于Task中
1310 if (activity == null) {
1311 Slog.w(TAG, "Binding with unknown activity: " + token);
1312 return 0;
1313 }
1314 }
1315
1316 int clientLabel = 0;
1317 PendingIntent clientIntent = null;
1318 final boolean isCallerSystem = callerApp.info.uid == Process.SYSTEM_UID;
1319
1320 if (isCallerSystem) {
1321 // Hacky kind of thing -- allow system stuff to tell us
1322 // what they are, so we can report this elsewhere for
1323 // others to know why certain services are running.
1324 service.setDefusable(true);
1325 clientIntent = service.getParcelableExtra(Intent.EXTRA_CLIENT_INTENT);
1326 if (clientIntent != null) {
1327 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
1328 if (clientLabel != 0) {
1329 // There are no useful extras in the intent, trash them.
1330 // System code calling with this stuff just needs to know
1331 // this will happen.
1332 service = service.cloneFilter();
1333 }
1334 }
1335 }
1336
1337 if ((flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
1338 mAm.enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
1339 "BIND_TREAT_LIKE_ACTIVITY");
1340 }
1341
1342 if ((flags & Context.BIND_ALLOW_WHITELIST_MANAGEMENT) != 0 && !isCallerSystem) {
1343 throw new SecurityException(
1344 "Non-system caller " + caller + " (pid=" + Binder.getCallingPid()
1345 + ") set BIND_ALLOW_WHITELIST_MANAGEMENT when binding service " + service);
1346 }
1347
1348 final boolean callerFg = callerApp.setSchedGroup != ProcessList.SCHED_GROUP_BACKGROUND;
1349 final boolean isBindExternal = (flags & Context.BIND_EXTERNAL_SERVICE) != 0;
1350
1351 ServiceLookupResult res =
1352 retrieveServiceLocked(service, resolvedType, callingPackage, Binder.getCallingPid(),
1353 Binder.getCallingUid(), userId, true, callerFg, isBindExternal);
//检索待绑定的ServiceRecord
1354 if (res == null) {
1355 return 0;
1356 }
1357 if (res.record == null) {
1358 return -1;
1359 }
1360 ServiceRecord s = res.record;
1361
1362 boolean permissionsReviewRequired = false;
1363
1364 // If permissions need a review before any of the app components can run,
1365 // we schedule binding to the service but do not start its process, then
1366 // we launch a review activity to which is passed a callback to invoke
1367 // when done to start the bound service's process to completing the binding.(权限相关)
1368 if (mAm.mPermissionReviewRequired) {
1369 if (mAm.getPackageManagerInternalLocked().isPermissionsReviewRequired(
1370 s.packageName, s.userId)) {
1371
1372 permissionsReviewRequired = true;
1373
1374 // Show a permission review UI only for binding from a foreground app
1375 if (!callerFg) {
1376 Slog.w(TAG, "u" + s.userId + " Binding to a service in package"
1377 + s.packageName + " requires a permissions review");
1378 return 0;
1379 }
1380
1381 final ServiceRecord serviceRecord = s;
1382 final Intent serviceIntent = service;
1383
1384 RemoteCallback callback = new RemoteCallback(
1385 new RemoteCallback.OnResultListener() {
1386 @Override
1387 public void onResult(Bundle result) {
1388 synchronized(mAm) {
1389 final long identity = Binder.clearCallingIdentity();
1390 try {
1391 if (!mPendingServices.contains(serviceRecord)) {
1392 return;
1393 }
1394 // If there is still a pending record, then the service
1395 // binding request is still valid, so hook them up. We
1396 // proceed only if the caller cleared the review requirement
1397 // otherwise we unbind because the user didn't approve.
1398 if (!mAm.getPackageManagerInternalLocked()
1399 .isPermissionsReviewRequired(
1400 serviceRecord.packageName,
1401 serviceRecord.userId)) {
1402 try {
1403 bringUpServiceLocked(serviceRecord,
1404 serviceIntent.getFlags(),
1405 callerFg, false, false);
1406 } catch (RemoteException e) {
1407 /* ignore - local call */
1408 }
1409 } else {
1410 unbindServiceLocked(connection);
1411 }
1412 } finally {
1413 Binder.restoreCallingIdentity(identity);
1414 }
1415 }
1416 }
1417 });
1418
1419 final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
1420 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
1421 | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
1422 intent.putExtra(Intent.EXTRA_PACKAGE_NAME, s.packageName);
1423 intent.putExtra(Intent.EXTRA_REMOTE_CALLBACK, callback);
1424
1425 if (DEBUG_PERMISSIONS_REVIEW) {
1426 Slog.i(TAG, "u" + s.userId + " Launching permission review for package "
1427 + s.packageName);
1428 }
1429
1430 mAm.mHandler.post(new Runnable() {
1431 @Override
1432 public void run() {
1433 mAm.mContext.startActivityAsUser(intent, new UserHandle(userId));
1434 }
1435 });
1436 }
1437 }
1438
1439 final long origId = Binder.clearCallingIdentity();
1440
1441 try {
1442 if (unscheduleServiceRestartLocked(s, callerApp.info.uid, false)) {
//从待重启服务中,移除当前的Service
1443 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "BIND SERVICE WHILE RESTART PENDING: "
1444 + s);
1445 }
1446
1447 if ((flags&Context.BIND_AUTO_CREATE) != 0) {
1448 s.lastActivity = SystemClock.uptimeMillis();
1449 if (!s.hasAutoCreateConnections()) {
//hasAutoCreateConnections:查看ServiceRecord.connections中是否有包含BIND_AUTO_CREATE flag的客户端 final ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections,key为IServiceConnection
1450 // This is the first binding, let the tracker know.
1451 ServiceState stracker = s.getTracker();
1452 if (stracker != null) {
1453 stracker.setBound(true, mAm.mProcessStats.getMemFactorLocked(),
1454 s.lastActivity);
1455 }
1456 }
1457 }
1458
1459 mAm.startAssociationLocked(callerApp.uid, callerApp.processName, callerApp.curProcState,
1460 s.appInfo.uid, s.name, s.processName);
//将绑定的发起方和接收方关联起来,同时保存在AMS定义的数据结构中
1461 // Once the apps have become associated, if one of them is caller is ephemeral
1462 // the target app should now be able to see the calling app
1463 mAm.grantEphemeralAccessLocked(callerApp.userId, service,
1464 s.appInfo.uid, UserHandle.getAppId(callerApp.uid));
1465
//根据Intent信息,检索出对应的IntentBindRecord(记录Intent,能启动哪个Service)
//进一步从IntentBindRecord中检索出AppBindRecord (记录进程,与哪个Service绑定)
//初次绑定时,将分别创建出IntentBindRecord和AppBindRecord!
//IntentBindRecord.apps用来记录所有使用该类intetn绑定同一个service的客户端信息。key是客户端进程ProcessRecord,value是AppBindRecord。因为不同的客户端可能使用相同的intent参数来绑定同一个service,所以IntentBindRecord要记录下这些客户端信息(客户端进程信息在AMS中的记录,一个AppBindRecord对应一个IntentBindRecord,(即用哪个Intent),一个ServiceRecord,(绑定哪个Service);对应多个ConnectionRecord,即一个进程可以使用同一个Intent,不同的ServiceConnection(与ConnectionRecord一一对应)绑定一个ServiceRecord);参考:bindService用到的各数据结构
1466 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp); //根据Intent和caller process两个要素查找对应的AppBindRecord对象
//返回相应Intent和发起bindService的客户端对应的AppBindRecord
1467 ConnectionRecord c = new ConnectionRecord(b, activity,
1468 connection, flags, clientLabel, clientIntent);
//根据AppBindRecord与ServiceConnection的binder对象,构建ConnectionRecord(AMS中的记录)
1469
1470 IBinder binder = connection.asBinder();//IServiceConnection connection
1471 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
//ServiceRecord中按照Connection的Binder保存ConnectionRecord,即一个ServiceRecord有多个由同一个ServiceConnection对应生成的ConnectionRecord
1472 if (clist == null) {
1473 clist = new ArrayList<ConnectionRecord>();
1474 s.connections.put(binder, clist);
1475 }
1476 clist.add(c);
1477 b.connections.add(c);//新的ConnectionRecord保存到ServiceRecord和AppBinderRecord中 AppBindRecord b(组合数据结构)
1478 if (activity != null) {
1479 if (activity.connections == null) {
1480 activity.connections = new HashSet<ConnectionRecord>();
1481 }
//如果Activity是绑定的发起方,那么ActiivtyRecord中也会记录ConnectionRecord
1482 activity.connections.add(c);
1483 }
1484 b.client.connections.add(c);//AppBinderRecord的client就是进程对应ProcessRecord
1485 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
1486 b.client.hasAboveClient = true;
1487 }
1488 if ((c.flags&Context.BIND_ALLOW_WHITELIST_MANAGEMENT) != 0) {
1489 s.whitelistManager = true;
1490 }
1491 if (s.app != null) {//如果Service所在进程之前已经启动过,更新进程优先级
1492 updateServiceClientActivitiesLocked(s.app, c, true);
1493 }
//ActiveServices中的mServiceConnections也将按照ServiceConnection的Binder保存ConnectionRecord list(ServiceRecord中也这样保存,ServiceRecord.connections,但两者意义不同,ServiceRecord中的list代表的是一个Service服务端,多个bind的来源;ActiveService中则没有个单个Service的限制,同一个客户端绑定多个Service的情况也会被记录在ConnectionRecord list中)
//注意到同一个Binder(IServiceConnection)可以对应多个ConnectionRecord
//这是因为,客户端可以用同一个ServiceConnection绑定多个Service
//每次绑定时,都会生成对应的ConnectionRecord,但这些ConnectionRecord共用相同的Binder
1494 clist = mServiceConnections.get(binder);
1495 if (clist == null) {
1496 clist = new ArrayList<ConnectionRecord>();
1497 mServiceConnections.put(binder, clist);
1498 }
1499 clist.add(c); //更新一些数据结构
1500
1501 if ((flags&Context.BIND_AUTO_CREATE) != 0) {
1502 s.lastActivity = SystemClock.uptimeMillis();
1503 if (bringUpServiceLocked(s, service.getFlags(), callerFg, false,
1504 permissionsReviewRequired) != null) {
//主要的工作在bringUpServiceLocked,前面基本上是创建个ConnectionRecord对象,添加到相关数据结构中
1505 return 0;
1506 }
1507 }
1508
1509 if (s.app != null) {
1510 if ((flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
1511 s.app.treatLikeActivity = true;
1512 }
1513 if (s.whitelistManager) {
1514 s.app.whitelistManager = true;
1515 }
1516 // This could have made the service more important.
1517 mAm.updateLruProcessLocked(s.app, s.app.hasClientActivities
1518 || s.app.treatLikeActivity, b.client);
1519 mAm.updateOomAdjLocked(s.app, true);
1520 }
1521
1522 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Bind " + s + " with " + b
1523 + ": received=" + b.intent.received
1524 + " apps=" + b.intent.apps.size()
1525 + " doRebind=" + b.intent.doRebind);
1526
1527 if (s.app != null && b.intent.received) {
1528 // Service is already running, so we can immediately
1529 // publish the connection.
1530 try {
1531 c.conn.connected(s.name, b.intent.binder, false);
1532 } catch (Exception e) {
1533 Slog.w(TAG, "Failure sending service " + s.shortName
1534 + " to connection " + c.conn.asBinder()
1535 + " (in " + c.binding.client.processName + ")", e);
1536 }
1537
1538 // If this is the first app connected back to this binding,
1539 // and the service had previously asked to be told when
1540 // rebound, then do so.
1541 if (b.intent.apps.size() == 1 && b.intent.doRebind) {
1542 requestServiceBindingLocked(s, b.intent, callerFg, true);
1543 }
1544 } else if (!b.intent.requested) {
1545 requestServiceBindingLocked(s, b.intent, callerFg, false);
1546 }
1547
1548 getServiceMapLocked(s.userId).ensureNotStartingBackgroundLocked(s);
1549
1550 } finally {
1551 Binder.restoreCallingIdentity(origId);
1552 }
1553
1554 return 1;
1555 }
ServiceRecord#retrieveAppBindingLocked
根据Intent和caller process两个因素找到对应的AppBindRecord
379 public AppBindRecord retrieveAppBindingLocked(Intent intent,
380 ProcessRecord app) {
381 Intent.FilterComparison filter = new Intent.FilterComparison(intent);
382 IntentBindRecord i = bindings.get(filter);
//先找到对应的IntentBindRecord
383 if (i == null) {
384 i = new IntentBindRecord(this, filter);
//没有就创建一个,并在ServiceRecord中存放
385 bindings.put(filter, i);
386 }
387 AppBindRecord a = i.apps.get(app);
388 if (a != null) {
389 return a;
390 }
391 a = new AppBindRecord(this, i, app);
392 i.apps.put(app, a);
//得到IntentBindRecord中的AppBindRecord,若不存在则创建一个并存放
393 return a;
394 }
ActiveServices#updateServiceClientActivitiesLocked
当客户端有Activity时,可能需要调整Service进程的优先级
1248 private boolean updateServiceClientActivitiesLocked(ProcessRecord proc,
1249 ConnectionRecord modCr, boolean updateLru) {
1250 if (modCr != null && modCr.binding.client != null) {
1251 if (modCr.binding.client.activities.size() <= 0) {
1252 // This connection is from a client without activities, so adding
1253 // and removing is not interesting.
1254 return false;
1255 }
1256 }
1257
1258 boolean anyClientActivities = false;
1259 for (int i=proc.services.size()-1; i>=0 && !anyClientActivities; i--) {
1260 ServiceRecord sr = proc.services.valueAt(i);
1261 for (int conni=sr.connections.size()-1; conni>=0 && !anyClientActivities; conni--) {
1262 ArrayList<ConnectionRecord> clist = sr.connections.valueAt(conni);
1263 for (int cri=clist.size()-1; cri>=0; cri--) {
1264 ConnectionRecord cr = clist.get(cri);
1265 if (cr.binding.client == null || cr.binding.client == proc) {
1266 // Binding to ourself is not interesting.
1267 continue;
1268 }
1269 if (cr.binding.client.activities.size() > 0) {
1270 anyClientActivities = true;
1271 break;
1272 }
1273 }
1274 }
1275 }
1276 if (anyClientActivities != proc.hasClientActivities) {
1277 proc.hasClientActivities = anyClientActivities;
1278 if (updateLru) {
1279 mAm.updateLruProcessLocked(proc, anyClientActivities, null);
1280 }
1281 return true;
1282 }
1283 return false;
1284 }
上面更新Service所在进程优先级的思路,从结果来看可以简化为: 如果当前Service所在进程,存在一个Service(一个进程内可以运行多个Service), 是由另一个含有Activity的进程绑定时(不论是否从Activity绑定),就会更新当前Service所在进程的优先级。
ActiveServices#bringUpServiceLocked
前面基本上是创建个ConnectionRecord对象,添加到各个数据结构中,这里是主要工作,startServiceLocked中也有调用
2198 private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
2199 boolean whileRestarting, boolean permissionsReviewRequired)
2200 throws TransactionTooLargeException {
2201 //Slog.i(TAG, "Bring up service:");
2202 //r.dump(" ");
2203
2204 if (r.app != null && r.app.thread != null) { //如果Service端已启动,直接发送参数
2205 sendServiceArgsLocked(r, execInFg, false);
2206 return null;
2207 }
2208
2209 if (!whileRestarting && mRestartingServices.contains(r)) {
2210 // If waiting for a restart, then do nothing.
2211 return null;
2212 }
2213
2214 if (DEBUG_SERVICE) {
2215 Slog.v(TAG_SERVICE, "Bringing up " + r + " " + r.intent + " fg=" + r.fgRequired);
2216 }
2217
2218 // We are now bringing the service up, so no longer in the
2219 // restarting state.
2220 if (mRestartingServices.remove(r)) { //从restart Service中移除
2221 clearRestartingIfNeededLocked(r);
2222 }
2223
2224 // Make sure this service is no longer considered delayed, we are starting it now.
2225 if (r.delayed) {
2226 if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "REM FR DELAY LIST (bring up): " + r);
2227 getServiceMapLocked(r.userId).mDelayedStartList.remove(r);
2228 r.delayed = false; //不再delay,从ServiceMap中的delay list也移除
2229 }
2230
2231 // Make sure that the user who owns this service is started. If not,
2232 // we don't want to allow it to run.
2233 if (!mAm.mUserController.hasStartedUserState(r.userId)) {
2234 String msg = "Unable to launch app "
2235 + r.appInfo.packageName + "/"
2236 + r.appInfo.uid + " for service "
2237 + r.intent.getIntent() + ": user " + r.userId + " is stopped";
2238 Slog.w(TAG, msg);
2239 bringDownServiceLocked(r); //将服务stop
2240 return msg;
2241 }
2242
2243 // Service is now being launched, its package can't be stopped.
2244 try {
2245 AppGlobals.getPackageManager().setPackageStoppedState(
2246 r.packageName, false, r.userId);
2247 } catch (RemoteException e) {
2248 } catch (IllegalArgumentException e) {
2249 Slog.w(TAG, "Failed trying to unstop package "
2250 + r.packageName + ": " + e);
2251 }
2252
2253 final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
2254 final String procName = r.processName;
2255 String hostingType = "service";
2256 ProcessRecord app;
2257
2258 if (!isolated) {
2259 app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
2260 if (DEBUG_MU) Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid
2261 + " app=" + app);
2262 if (app != null && app.thread != null) {
2263 try {
2264 app.addPackage(r.appInfo.packageName, r.appInfo.versionCode, mAm.mProcessStats);
2265 realStartServiceLocked(r, app, execInFg); //进程启动但Service没启动,启动Service
2266 return null;
2267 } catch (TransactionTooLargeException e) {
2268 throw e;
2269 } catch (RemoteException e) {
2270 Slog.w(TAG, "Exception when starting service " + r.shortName, e);
2271 }
2272
2273 // If a dead object exception was thrown -- fall through to
2274 // restart the application.
2275 }
2276 } else {
2277 // If this service runs in an isolated process, then each time
2278 // we call startProcessLocked() we will get a new isolated
2279 // process, starting another process if we are currently waiting
2280 // for a previous process to come up. To deal with this, we store
2281 // in the service any current isolated process it is running in or
2282 // waiting to have come up.
2283 app = r.isolatedProc;
2284 if (WebViewZygote.isMultiprocessEnabled()
2285 && r.serviceInfo.packageName.equals(WebViewZygote.getPackageName())) {
2286 hostingType = "webview_service";
2287 }
2288 }
2289
2290 // Not running -- get it started, and enqueue this service record
2291 // to be executed when the app comes up.
2292 if (app == null && !permissionsReviewRequired) {
2293 if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
2296 hostingType, r.name, false, isolated, false, r.callerPackage)) == null) {
2297 String msg = "Unable to launch app "
2298 + r.appInfo.packageName + "/"
2299 + r.appInfo.uid + " for service "
2300 + r.intent.getIntent() + ": process is bad";
2301 Slog.w(TAG, msg);
2302 bringDownServiceLocked(r);
2303 return msg;
2304 }
2305 if (isolated) {
2306 r.isolatedProc = app;
2307 }
2308 }
2309
2310 if (r.fgRequired) {
2311 if (DEBUG_FOREGROUND_SERVICE) {
2312 Slog.v(TAG, "Whitelisting " + UserHandle.formatUid(r.appInfo.uid)
2313 + " for fg-service launch");
2314 }
2315 mAm.tempWhitelistUidLocked(r.appInfo.uid,
2316 SERVICE_START_FOREGROUND_TIMEOUT, "fg-service-launch");
2317 }
2318
2319 if (!mPendingServices.contains(r)) {
2320 mPendingServices.add(r);
2321 }
2322
2323 if (r.delayedStop) {
2324 // Oh and hey we've already been asked to stop!
2325 r.delayedStop = false;
2326 if (r.startRequested) {
2327 if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE,
2328 "Applying delayed stop (in bring up): " + r);
2329 stopServiceLocked(r);
2330 }
2331 }
2332
2333 return null;
2334 }
ActiveServices#realStartServiceLocked
2346 private final void realStartServiceLocked(ServiceRecord r,
2347 ProcessRecord app, boolean execInFg) throws RemoteException {
2348 if (app.thread == null) {
2349 throw new RemoteException();
2350 }
2351 if (DEBUG_MU)
2352 Slog.v(TAG_MU, "realStartServiceLocked, ServiceRecord.uid = " + r.appInfo.uid
2353 + ", ProcessRecord.uid = " + app.uid);
2354 r.app = app;
2355 r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
2356
2357 final boolean newService = app.services.add(r);
2358 bumpServiceExecutingLocked(r, execInFg, "create");
2359 mAm.updateLruProcessLocked(app, false, null);
2360 updateServiceForegroundLocked(r.app, /* oomAdj= */ false);
2361 mAm.updateOomAdjLocked();
2362
2363 boolean created = false;
2364 try {
2365 if (LOG_SERVICE_START_STOP) {
2366 String nameTerm;
2367 int lastPeriod = r.shortName.lastIndexOf('.');
2368 nameTerm = lastPeriod >= 0 ? r.shortName.substring(lastPeriod) : r.shortName;
2369 EventLogTags.writeAmCreateService(
2370 r.userId, System.identityHashCode(r), nameTerm, r.app.uid, r.app.pid);
2371 }
2372 synchronized (r.stats.getBatteryStats()) {
2373 r.stats.startLaunchedLocked();
2374 }
2375 mAm.notifyPackageUse(r.serviceInfo.packageName,
2376 PackageManager.NOTIFY_PACKAGE_USE_SERVICE);
2377 app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
2378 app.thread.scheduleCreateService(r, r.serviceInfo,
2379 mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
2380 app.repProcState);
2381 r.postNotification();
2382 created = true;
2383 } catch (DeadObjectException e) {
2384 Slog.w(TAG, "Application dead when creating service " + r);
2390 mAm.appDiedLocked(app);
2391 throw e;
2392 } finally {
2393 if (!created) {
2394 // Keep the executeNesting count accurate.
2395 final boolean inDestroying = mDestroyingServices.contains(r);
2396 serviceDoneExecutingLocked(r, inDestroying, inDestroying);
2397
2398 // Cleanup.
2399 if (newService) {
2400 app.services.remove(r);
2401 r.app = null;
2402 if (SERVICE_RESCHEDULE && DEBUG_DELAYED_SERVICE) {
2403 Slog.w(TAG, " Failed to create Service !!!! ."
2404 +"This will introduce huge delay... "
2405 +r.shortName + " in " + r.restartDelay + "ms");
2406 }
2407 }
2408
2409 // Retry.
2410 if (!inDestroying) {
2411 scheduleServiceRestartLocked(r, false);
2412 }
2413 }
2414 }
2415
2416 if (r.whitelistManager) {
2417 app.whitelistManager = true;
2418 }
2419
2420 requestServiceBindingsLocked(r, execInFg);
//对于bindService create服务实例之后,调用sendServiceArgsLocked之前,调用这里,用于注册服务(publishService)
2421
2422 updateServiceClientActivitiesLocked(app, null, true);
2423
2424 // If the service is in the started state, and there are no
2425 // pending arguments, then fake up one so its onStartCommand() will
2426 // be called.
2427 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
2428 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
2429 null, null, 0));
2430 }
2431
2432 sendServiceArgsLocked(r, execInFg, true);
2433
2434 if (r.delayed) {
2435 if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "REM FR DELAY LIST (new proc): " + r);
2436 getServiceMapLocked(r.userId).mDelayedStartList.remove(r);
2437 r.delayed = false;
2438 }
2439
2440 if (r.delayedStop) {
2441 // Oh and hey we've already been asked to stop!
2442 r.delayedStop = false;
2443 if (r.startRequested) {
2444 if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE,
2445 "Applying delayed stop (from start): " + r);
2446 stopServiceLocked(r);
2447 }
2448 }
2449 }
bindService与startService相比,在realStartServiceLocked中要注意的是requestServiceBindingsLocked(r, execInFg);
bindService和startService在realStartServiceLocked中的区别在requestServiceBindingsLocked
在create Service实例之后,向Service实例的binder对象发送命令sendServiceArgsLocked之前,回调Service的onStartCommand函数之前
注意点1:
一般bindService时不会调用onStartCommand,因为只有startServiceLocked中会修改
r.startRequested = true;
r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
service, neededGrants, callingUid));
只有ServiceRecord中有pendingStarts,才可能调用sendServiceArgsLocked时会调用到Service中onStartCommand
2451 private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg,
2452 boolean oomAdjusted) throws TransactionTooLargeException {
2453 final int N = r.pendingStarts.size();
2454 if (N == 0) {
2455 return;
2456 }
对于一般的bindService而言,sendServiceArgsLocked是会直接返回的
注意点2:
requestServiceBindingsLocked 用于publishService,将Service实例对应的binder对象注册到AMS中,前面向服务端传递参数时,如
r.app.thread.scheduleServiceArgs(r, slice);
ActivityThread中的
final ArrayMap<IBinder, Service> mServices = new ArrayMap<>(); //IBinder为ServiceRecord在服务端的binder对象
服务端保存了AMS中的ServiceRecord对应的IBinder对象,用于查找究竟对应服务端的哪个Service实例;
startService时为何不需要pushService?因为AMS中保持服务端Service实例的binder对象是没有必要的,通过客户端通过startService只能调用服务端的onStartCommand,并没有持有相关binder对象与Service服务二次通信的必要,相当于流程都是固定的;
而bindService之所以要pushService使AMS中的IntentBindRecord.binder保存Service实例的IBinder对象是为了方便客户端进行查找;原因是客户端可能通过得到的Ibinder对象调用Service实例中实现的其他接口;流程不固定;因此将接口保存在AMS中以方便客户端二次查找时不用重复调用onBind返回Service的binder代理
ActiveServices# requestServiceBindingsLocked
2336 private final void requestServiceBindingsLocked(ServiceRecord r, boolean execInFg)
2337 throws TransactionTooLargeException {
2338 for (int i=r.bindings.size()-1; i>=0; i--) {
2339 IntentBindRecord ibr = r.bindings.valueAt(i); //对绑定Service的每个IntentBindRecord进行操作requestServiceBindingLocked
2340 if (!requestServiceBindingLocked(r, ibr, execInFg, false)) { //依次处理所有绑定请求,只要一次绑定失败,就break
2341 break;
2342 }
2343 }
2344 }
IntentBindRecord被处理过后,requested将被置为true
因此只有第一次处理的请求,和重新绑定时,才会处理,这就是说,客户端第一次绑定Service时,onBind函数才会被回调的原因
1913 private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i,
1914 boolean execInFg, boolean rebind) throws TransactionTooLargeException {
1915 if (r.app == null || r.app.thread == null) {
1916 // If service is not currently running, can't yet bind.
1917 return false;
1918 }
1919 if (DEBUG_SERVICE) Slog.d(TAG_SERVICE, "requestBind " + i + ": requested=" + i.requested
1920 + " rebind=" + rebind);
1921 if ((!i.requested || rebind) && i.apps.size() > 0) {
1922 try {
//发送消息前记录ServiceRecord状态信息,判断ANR等
1923 bumpServiceExecutingLocked(r, execInFg, "bind");
1924 r.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
//调整服务端进程的优先级
1925 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,
1926 r.app.repProcState);
1927 if (!rebind) {
1928 i.requested = true; //IntentBindRecord.requested = true
// /** Set when we have initiated a request for this binder. */
1929 }
1930 i.hasBound = true;
1931 i.doRebind = false;
1932 } catch (TransactionTooLargeException e) {
1933 // Keep the executeNesting count accurate.
1934 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Crashed while binding " + r, e);
1935 final boolean inDestroying = mDestroyingServices.contains(r);
1936 serviceDoneExecutingLocked(r, inDestroying, inDestroying); //这里调用serviceDoneExecutingLocked用来Keep the executeNesting count accurate.
1937 throw e;
1938 } catch (RemoteException e) {
1939 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Crashed while binding " + r);
1940 // Keep the executeNesting count accurate.
1941 final boolean inDestroying = mDestroyingServices.contains(r);
1942 serviceDoneExecutingLocked(r, inDestroying, inDestroying);
1943 return false;
1944 }
1945 }
1946 return true;
1947 }
ActivityThread#scheduleBindService
817 public final void scheduleBindService(IBinder token, Intent intent,
818 boolean rebind, int processState) {
819 updateProcessState(processState, false);
820 BindServiceData s = new BindServiceData();
821 s.token = token; //ServiceRecord对应的binder
822 s.intent = intent;
823 s.rebind = rebind;
824
825 if (DEBUG_SERVICE)
826 Slog.v(TAG, "scheduleBindService token=" + token + " intent=" + intent + " uid="
827 + Binder.getCallingUid() + " pid=" + Binder.getCallingPid());
828 sendMessage(H.BIND_SERVICE, s);
829 }
1670 case BIND_SERVICE:
1671 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind");
1672 handleBindService((BindServiceData)msg.obj);
1673 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1674 break;
ActivityThread#handleBindService
3550 private void handleBindService(BindServiceData data) {
3551 Service s = mServices.get(data.token);
3552 if (DEBUG_SERVICE)
3553 Slog.v(TAG, "handleBindService s=" + s + " rebind=" + data.rebind);
3554 if (s != null) {
3555 try {
3556 data.intent.setExtrasClassLoader(s.getClassLoader());
3557 data.intent.prepareToEnterProcess();
3558 try {
3559 if (!data.rebind) {
3560 IBinder binder = s.onBind(data.intent); //调用Service的onBind函数,返回一个binder对象
3561 ActivityManager.getService().publishService(
3562 data.token, data.intent, binder); //调用AMS的pushService函数,发布服务,binder代表Service实例的binder对象
3563 } else {
3564 s.onRebind(data.intent);
3565 ActivityManager.getService().serviceDoneExecuting(
3566 data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
3567 }
3568 ensureJitEnabled();
3569 } catch (RemoteException ex) {
3570 throw ex.rethrowFromSystemServer();
3571 }
3572 } catch (Exception e) {
3573 if (!mInstrumentation.onException(s, e)) {
3574 throw new RuntimeException(
3575 "Unable to bind to service " + s
3576 + " with " + data.intent + ": " + e.toString(), e);
3577 }
3578 }
3579 }
3580 }
ActivityManagerService#publishService
20692 public void publishService(IBinder token, Intent intent, IBinder service) {
20693 // Refuse possible leaked file descriptors
20694 if (intent != null && intent.hasFileDescriptors() == true) {
20695 throw new IllegalArgumentException("File descriptors passed in Intent");
20696 }
20697
20698 synchronized(this) {
20699 if (!(token instanceof ServiceRecord)) {
20700 throw new IllegalArgumentException("Invalid service token");
20701 }
20702 mServices.publishServiceLocked((ServiceRecord)token, intent, service);
20703 }
20704 }
ActiveServices#publishServiceLocked
1703 void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {
1704 final long origId = Binder.clearCallingIdentity(); //原来是从服务端进程调用的,因为现在AMS中要调用其他接口,所以需要临时将pid和uid设为当前进程,以通过权限检查
1705 try {
1706 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "PUBLISHING " + r
1707 + " " + intent + ": " + service);
1708 if (r != null) {
1709 Intent.FilterComparison filter
1710 = new Intent.FilterComparison(intent);
1711 IntentBindRecord b = r.bindings.get(filter); //根据ServiceRecord和Intent得到对应的IntentBindRecord
1712 if (b != null && !b.received) {
//Service返回的Binder保存到IntentBinderRecord中
//这样下次调用bindService时,就可以直接从IntentBinderRecord中返回Service的Binder对象了
//毕竟从上述流程也可以看出,只有第一次Bind Service时才会调用Service的onBind接口
1713 b.binder = service;
1714 b.requested = true;
1715 b.received = true;
///** Set when we have received the requested binder. */
//IntentBindRecord对应的客户端第一次bindService导致返回了Service的binder代理(onBind函数返回值),
//这里置为true,代表相应IBinder对象已经注册进AMS中,后续无需重复操作
1716 for (int conni=r.connections.size()-1; conni>=0; conni--) {
//ActiveServices中的mServiceConnections也将按照ServiceConnection的Binder保存ConnectionRecord list
//(ServiceRecord中也这样保存,ServiceRecord.connections) 相当于AMS中的ServiceRecord中也根据客户端ServiceConnection的binder对象保存其相应的ConnectionRecord list
1717 ArrayList<ConnectionRecord> clist = r.connections.valueAt(conni);
1718 for (int i=0; i<clist.size(); i++) {
1719 ConnectionRecord c = clist.get(i);
1720 if (!filter.equals(c.binding.intent.intent)) {
//多个客户端以相同的Intent绑定服务时,均会回调
1721 if (DEBUG_SERVICE) Slog.v(
1722 TAG_SERVICE, "Not publishing to: " + c);
1723 if (DEBUG_SERVICE) Slog.v(
1724 TAG_SERVICE, "Bound intent: " + c.binding.intent.intent);
1725 if (DEBUG_SERVICE) Slog.v(
1726 TAG_SERVICE, "Published intent: " + intent);
1727 continue; //Intent不相等时,就继续,不回调
//即相当于只处理当前IntentBindRecord所对应的ConnectionRecord(ServiceConnection)
1728 }
1729 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Publishing to: " + c);
1730 try {
1731 c.conn.connected(r.name, service, false);
//final IServiceConnection conn 回掉ServiceConnection(service为onBind的返回值对象)中重载的函数
1732 } catch (Exception e) {
1733 Slog.w(TAG, "Failure sending service " + r.name +
1734 " to connection " + c.conn.asBinder() +
1735 " (in " + c.binding.client.processName + ")", e);
1736 }
1737 }
1738 }
1739 }
1740
1741 serviceDoneExecutingLocked(r, mDestroyingServices.contains(r), false);
1742 }
1743 } finally {
1744 Binder.restoreCallingIdentity(origId);
1745 }
1746 }
至此,客户端与Service绑定的相关工作结束,下面可以看回调的流程:
1.在publishServiceLocked中,第一次绑定后在AMS中的IntentBinfRecord中注册Service binder之后,调用 c.conn.connected(r.name, service, false);
2.回到ActiveServices#bindServiceLocked中,调用c.conn.connected(s.name, b.intent.binder, false);
注意第二个参数的区别,当IntentBindRecord received被置为true,说明Service binder已经注册成功,后面就是用IntentBindRecord.binder中保存的就能代表Service实例的相应对象
1509 if (s.app != null) {
1510 if ((flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
1511 s.app.treatLikeActivity = true;
1512 }
1513 if (s.whitelistManager) {
1514 s.app.whitelistManager = true;
1515 }
1516 // This could have made the service more important.
1517 mAm.updateLruProcessLocked(s.app, s.app.hasClientActivities
1518 || s.app.treatLikeActivity, b.client);
1519 mAm.updateOomAdjLocked(s.app, true);
1520 }
1521
1522 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Bind " + s + " with " + b
1523 + ": received=" + b.intent.received
1524 + " apps=" + b.intent.apps.size()
1525 + " doRebind=" + b.intent.doRebind);
1526
1527 if (s.app != null && b.intent.received) {
//当Service已经启动过,并且以对应的Intent绑定过时
//可直接进行回调,返回IntentBinderRecord中的binder对象
1528 // Service is already running, so we can immediately
1529 // publish the connection.
1530 try {
1531 c.conn.connected(s.name, b.intent.binder, false);
1532 } catch (Exception e) {
1533 Slog.w(TAG, "Failure sending service " + s.shortName
1534 + " to connection " + c.conn.asBinder()
1535 + " (in " + c.binding.client.processName + ")", e);
1536 }
1537
1538 // If this is the first app connected back to this binding,
1539 // and the service had previously asked to be told when
1540 // rebound, then do so.
1541 if (b.intent.apps.size() == 1 && b.intent.doRebind) {
//处理重新绑定的情况
1542 requestServiceBindingLocked(s, b.intent, callerFg, true);
1543 }
1544 } else if (!b.intent.requested) {
//客户端不使用BIND_AUTO_CREATE flag绑定服务时,
//若对应服务并没有启动,但服务端进程启动了,就会进入这个分支
//requestServiceBindingLocked检测到对应服务没有启动,不会进行实际的绑定工作
1545 requestServiceBindingLocked(s, b.intent, callerFg, false);
1546 }
1547
1548 getServiceMapLocked(s.userId).ensureNotStartingBackgroundLocked(s);
1549
1550 } finally {
1551 Binder.restoreCallingIdentity(origId);
1552 }
1553
1554 return 1;
1555 }
客户端注册到AMS的Binder通信服务端,实际上是LoadedApk的内部类ServiceDispatcher中的InnerConnection。
因此客户端与Service绑定成功后,AMS回调的是InnerConnection中的connected函数
LoadApk#ServiceDispatcher$InnnerConnection
ServiceDispatcher:客户端持有的数据结构,保存有客户端的ServiceConnection对象及其对应的binder(InnerConnection,作为binder通信的服务端,供AMS回调)
1506 private static class InnerConnection extends IServiceConnection.Stub {
1507 final WeakReference<LoadedApk.ServiceDispatcher> mDispatcher; //WeakReference的使用场景
//静态内部类持有外部对象(用WeakReference引用)
1508
1509 InnerConnection(LoadedApk.ServiceDispatcher sd) {
1510 mDispatcher = new WeakReference<LoadedApk.ServiceDispatcher>(sd);
1511 }
1512
1513 public void connected(ComponentName name, IBinder service, boolean dead)
1514 throws RemoteException {
1515 LoadedApk.ServiceDispatcher sd = mDispatcher.get();
1516 if (sd != null) { //判断其是否已经被回收
1517 sd.connected(name, service, dead);
1518 }
1519 }
1520 }
1586 public void connected(ComponentName name, IBinder service, boolean dead) {
1587 if (mActivityThread != null) {
1588 mActivityThread.post(new RunConnection(name, service, 0, dead));
//mActivityThread ServiceDispatcher 保存的handler,一般是主线程handler,但有可能通过bindServiceAsUser来传递其他handler
1589 } else {
1590 doConnected(name, service, dead);
1591 }
1592 }
1671 private final class RunConnection implements Runnable {
1672 RunConnection(ComponentName name, IBinder service, int command, boolean dead) {
1673 mName = name;
1674 mService = service;
1675 mCommand = command;
1676 mDead = dead;
1677 }
1678
1679 public void run() {
1680 if (mCommand == 0) {
1681 doConnected(mName, mService, mDead); ..调用doConnected
1682 } else if (mCommand == 1) {
1683 doDeath(mName, mService);
1684 }
1685 }
LoadApk#ServiceDispatcher
客户端的ServiceDispatcher中
1522 private final ArrayMap<ComponentName, ServiceDispatcher.ConnectionInfo> mActiveConnections
1523 = new ArrayMap<ComponentName, ServiceDispatcher.ConnectionInfo>();
从以上ServiceDispatcher的逻辑来看,客户端可以用同一个ServiceConnection绑定多个Service, 绑定成功后为每个Service创建对应的ConnectionInfo,并按Service组件名保存到mActiveConnections中。
1501 private static class ConnectionInfo {
1502 IBinder binder; //保存Service实例的binder对象
1503 IBinder.DeathRecipient deathMonitor;
1504 }
ServiceDispatcher#doConnected
1602 public void doConnected(ComponentName name, IBinder service, boolean dead) {
1603 ServiceDispatcher.ConnectionInfo old;
1604 ServiceDispatcher.ConnectionInfo info;
1605
1606 synchronized (this) {
1607 if (mForgotten) {
1608 // We unbound before receiving the connection; ignore
1609 // any connection received.
1610 return;
1611 }
1612 old = mActiveConnections.get(name);
1613 if (old != null && old.binder == service) {
1614 // Huh, already have this one. Oh well!
1615 return;
1616 }
1617
1618 if (service != null) {
1619 // A new service is being connected... set it all up.
1620 info = new ConnectionInfo();
1621 info.binder = service;
1622 info.deathMonitor = new DeathMonitor(name, service);
1623 try {
1624 service.linkToDeath(info.deathMonitor, 0);
//为Service的binder对象注册死亡代理
1625 mActiveConnections.put(name, info);
1626 } catch (RemoteException e) {
1627 // This service was dead before we got it... just
1628 // don't do anything with it.
1629 mActiveConnections.remove(name);
1630 return;
1631 }
1632
1633 } else {
1634 // The named service is being disconnected... clean up.
1635 mActiveConnections.remove(name);
1636 }
1637
1638 if (old != null) {
1639 old.binder.unlinkToDeath(old.deathMonitor, 0);
1640 }
1641 }
1642
1643 // If there was an old service, it is now disconnected.
1644 if (old != null) {
1645 mConnection.onServiceDisconnected(name);
1646 }
1647 if (dead) {
1648 mConnection.onBindingDied(name);
1649 }
1650 // If there is a new service, it is now connected.
1651 if (service != null) {
1652 mConnection.onServiceConnected(name, service); //调用onServiceConnected方法
1653 }
1654 }
bindService流程图
bindService.png参考:
Android 7.0 ActivityManagerService(6) Service相关流程分析
bindService用到的各数据结构
网友评论