美文网首页android之基础学习攻克
Service相关流程学习-Bind Service

Service相关流程学习-Bind Service

作者: weiinter105 | 来源:发表于2018-11-30 23:48 被阅读0次

梳理下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用到的各数据结构

相关文章

网友评论

    本文标题:Service相关流程学习-Bind Service

    本文链接:https://www.haomeiwen.com/subject/ndbkcqtx.html