美文网首页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