Android 深入理解 Service 的启动和绑定

Service 的启动原理

1.Service 的启动有哪几种方式
2.Service 启动过程中主要流程有哪些
3.Service 启动过程中涉及哪些参与者,通信过程是怎样的

startService()

    @Override
    public ComponentName startService(Intent service) {
    
    
        return mBase.startService(service);
    }

ContextImpl 的 startService()

	// 调用了 startService 下面的 startServiceCommon() 函数
    @Override
    public ComponentName startService(Intent service) {
    
    
        warnIfCallingFromSystemProcess();
        return startServiceCommon(service, false, mUser);
    }

    private ComponentName startServiceCommon(Intent service, boolean requireForeground,
            UserHandle user) {
    
    
        try {
    
    
            validateServiceIntent(service);
            service.prepareToLeaveProcess(this);
            // 拿到了 AMS 的 binder 对象,然后调用 AMS 的 startService() 函数 同时把  applicationThread binder 对象作为参数给 AMS 传入。
            ComponentName cn = ActivityManager.getService().startService(
                mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
                            getContentResolver()), requireForeground,
                            getOpPackageName(), user.getIdentifier());
            // 。。。
            return cn;
        } catch (RemoteException e) {
    
    
            throw e.rethrowFromSystemServer();
        }
    }

startServiceCommon() 函数,拿到了 AMS 的 binder 对象,然后调用其 startService() 函数,并把 ApplicationThread 作为参数给 AMS 传过去。

  • 接下来看一下 AMS 的 startService() 函数。
    @Override
    public ComponentName startService(IApplicationThread caller, Intent service,
            String resolvedType, boolean requireForeground, String callingPackage, int userId)
            throws TransactionTooLargeException {
    
    
        enforceNotIsolatedCaller("startService");
        synchronized(this) {
    
    
            ComponentName res;
            try {
    
    
                res = mServices.startServiceLocked(caller, service,
                        resolvedType, callingPid, callingUid,
                        requireForeground, callingPackage, userId);
            } finally {
    
    
                Binder.restoreCallingIdentity(origId);
            }
            return res;
        }
    }

AMS 的 startService 中调用了ActiveServices 的 mServices.startServiceLocked() 方法

  • mServices.startServiceLocked()
    ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,...)throws TransactionTooLargeException {
    
    
		// 根据传入的 Intent 查找到 ServiceRecord 对象。
        ServiceLookupResult res =
            retrieveServiceLocked(service, resolvedType, callingPackage,
                    callingPid, callingUid, userId, true, callerFg, false, false);
        if (res == null) {
    
    
            return null;
        }
        if (res.record == null) {
    
    
            return new ComponentName("!", res.permission != null
                    ? res.permission : "private to package");
        }
		// 每个应用端都会有一个 ServiceRecord 对象
        ServiceRecord r = res.record;
		// 。。。。
		// new 了一个 ServiceRecord.StartItem 添加到 pendingStarts ,这个是为了启动后调用 onStartCommond() 用
        r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
                service, neededGrants, callingUid));
		// 最后调用了 startServiceInnerLocked() 函数
		ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
        return cmp;
}

startServiceLocked 获取到的 ServiceRecord 是每个应用都会有的一个对象,记录了应用内运行的或者将要运行的Service 信息。然后把将要启动的Service创建一个 ServiceRecord.StartItem对象添加到代执行列表pendingStarts中,最后调用 startServiceInnerLocked 继续启动流程

  • startServiceInnerLocked()
    ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
            boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
    
    
	// 调用了 bringUpServiceLocked() 继续流程
	String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);


}
  • bringUpServiceLocked()
    private String bringUpServiceLocked(ServiceRecord r,....){
    
    
		// 首先查看 Service 是否启动了 app 代表 Service 所在的进程
        if (r.app != null && r.app.thread != null) {
    
    
        // 如果启动了则 调用sendServiceArgsLocked() 其内部线从通过pendingStarts取到Service,然后通过 binder 调用回调到应用端的 Service 的 onStartCommand() 方法。
            sendServiceArgsLocked(r, execInFg, false);
            return null;
        }
        // 下面是 Service 还没有启动的情况
        ProcessRecord app;
		// 先判断进程是否启动了
        app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
        // 如果进程已经启动
        if (app != null && app.thread != null) {
    
    
                try {
    
    
                    app.addPackage(r.appInfo.packageName, r.appInfo.longVersionCode, mAm.mProcessStats);	
                    // 调用 realStartServiceLocked() 真正的启动 Service 去
                    realStartServiceLocked(r, app, execInFg);
                    // 然后结束方法 返回 null
                    return null;
                } 
            }
            // 如果进程未启动 或者 app 还没有就绪
	if (app == null && !permissionsReviewRequired) {
    
    
	// 调用 startProcessLocked() 去先启动进程
            if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
                    hostingType, r.name, false, isolated, false)) == null) {
    
    
                bringDownServiceLocked(r);
                return msg;
            }
        }
    // 然后将 ServiceRecord 添加到 mPendingServices列表中;mPendingServices 是用来等进程启动后再来处理 Service 的启动。
        if (!mPendingServices.contains(r)) {
    
    
            mPendingServices.add(r);
        }
}

回顾一下之前讲过的进程启动流程
Android Application 的理解
Zygote 启动应用程序流程
Android启动流程大致如下:
在这里插入图片描述
当应用启动之后,应用会通过 attachApplication() 处理一些应用组件。

private final boolean attachApplicationLocked(IApplicationThread thread,
            int pid, int callingUid, long startSeq) {
    
    
	// 内部会调用这行代码 继续处理 Service 的信息
	mServices.attachApplicationLocked(app, processName);
	return true;
}
  • ActiveServices 的 mServices.attachApplicationLocked(app, processName);
    boolean attachApplicationLocked(ProcessRecord proc, String processName)
            throws RemoteException {
    
    
        boolean didSomething = false;
        if (mPendingServices.size() > 0) {
    
    
            ServiceRecord sr = null;
            // for 循环里处理每一个 service 信息
                for (int i=0; i<mPendingServices.size(); i++) {
    
    
                    // ... 
                    realStartServiceLocked(sr, proc, sr.createdFromFg);
                }
        }
       	// ... 
        return didSomething;
    }

attachApplicationLocked() 内部通过 for 循环为每个 Service 调用了 realStartServiceLocked() 函数

  • realStartServiceLocked() 真正启动 service 的方法
    private final void realStartServiceLocked(ServiceRecord r,
            ProcessRecord app, boolean execInFg) throws RemoteException {
    
    
       		// app.thread为 binder 调用,调用到了 应用端的ApplicationThread 的 scheduleCreateService() 函数
       		// 然后执行 onCreate() 回调 ServiceRecord 其实是一个 binder 对象传回给了客户端,应用端给保存了下来
            app.thread.scheduleCreateService(r, r.serviceInfo,
                    mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
                    app.repProcState);
            // 调用 sendServiceArgsLocked() 回调到应用端的 onStartCommond() 函数
   	        sendServiceArgsLocked(r, execInFg, true);
    }

realStartServiceLocked() 函数先是通过 IPC 调用了客户端的 ApplicationThread 的 scheduleCreateService() 函数进行创建 Service 同时调用 Service 的 onCreate() 函数,binder 调用时将 ServiceRecord 传回客户端。

  • scheduleCreateService() 函数
        public final void scheduleCreateService(IBinder token,
                ServiceInfo info, CompatibilityInfo compatInfo, int processState) {
    
    
            updateProcessState(processState, false);
            CreateServiceData s = new CreateServiceData();
            s.token = token;
            s.info = info;
            s.compatInfo = compatInfo;

            sendMessage(H.CREATE_SERVICE, s);
        }

其发送了 handler 信息,将 CreateServiceData() 传入 ,Handler 接收的时候调用了 handleCreateService((CreateServiceData)msg.obj); 函数,所以接下来直接看此函数内部时如何处理的。

  • handleCreateService()
    private void handleCreateService(CreateServiceData data) {
    
    
        LoadedApk packageInfo = getPackageInfoNoCheck(
                data.info.applicationInfo, data.compatInfo);
        Service service = null;
        try {
    
    
        	// 先通过 ClassLoader 创建 Service 类
            java.lang.ClassLoader cl = packageInfo.getClassLoader();
            service = packageInfo.getAppFactory()
                    .instantiateService(cl, data.info.name, data.intent);
        }
        try {
    
    
          	// 先创建 context 对象
            ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
            context.setOuterContext(service);
			// 创建 application 对象,创建好直接返回 application 对象
            Application app = packageInfo.makeApplication(false, mInstrumentation);
            // 调用 Service 的 attach() 函数
            service.attach(context, this, data.info.name, data.token, app,
                    ActivityManager.getService());
            // 调用 service.onCreate(); 函数
            service.onCreate();
            // 将 data.token 就是之前说的那个 ServiceRecord 存储 map 中
            mServices.put(data.token, service);
            try {
    
    
                ActivityManager.getService().serviceDoneExecuting(
                        data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
            } catch (RemoteException e) {
    
    
                throw e.rethrowFromSystemServer();
            }
        } 
    }

  • sendServiceArgsLocked() 是怎么触发 onStartCommond() 函数的
    private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg,
            boolean oomAdjusted) throws TransactionTooLargeException {
    
    
        final int N = r.pendingStarts.size();
        
        try {
    
    
            r.app.thread.scheduleServiceArgs(r, slice);
        }
        // ...
    }

sendServiceArgsLocked 中通过 IPC 操作调用到了客户端 ApplicationThread 中的 scheduleServiceArgs() 函数

  • scheduleServiceArgs()
        public final void scheduleServiceArgs(IBinder token, ParceledListSlice args) {
    
    
            List<ServiceStartArgs> list = args.getList();

            for (int i = 0; i < list.size(); i++) {
    
    
                ServiceStartArgs ssa = list.get(i);
                ServiceArgsData s = new ServiceArgsData();
                s.token = token;
                //...
                sendMessage(H.SERVICE_ARGS, s);
            }
        }

在 scheduleServiceArgs 中 封装了 ServiceStartArgs 后通过 Hander 发送了 SERVICE_ARGS 消息。接收后的方法如下

                case SERVICE_ARGS:
                    handleServiceArgs((ServiceArgsData)msg.obj);
                    break;
  • handleServiceArgs()
    private void handleServiceArgs(ServiceArgsData data) {
    
    
     // 先获取到 Service 
        Service s = mServices.get(data.token);
        if (s != null) {
    
    
            try {
    
    
                int res;
                if (!data.taskRemoved) {
    
    
                // 调用的Service 的 onStartCommand() 所以 onStartCommand 是在主线程掉用的
                    res = s.onStartCommand(data.args, data.flags, data.startId);
                } 
                try {
    
    
                    ActivityManager.getService().serviceDoneExecuting(
                            data.token, SERVICE_DONE_EXECUTING_START, data.startId, res);
                } 
                ensureJitEnabled();
            }
        }
    }

总结一下启动流程

网上找了几张图
在这里插入图片描述

  • 进程角度来看都有哪些参与启动 Service
    在这里插入图片描述

Service 的绑定原理

bindService()

回忆一下 bindService() 的用法

    // 定义 aidl 接口
    IMyAidlInterface myAidlInterface;
    // 创建 ServiceConnection
    private ServiceConnection serviceConnection = new ServiceConnection() {
    
    
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
    
    
            myAidlInterface = myAidlInterface.Stub.asInterface(service);
             // 发起接口调用
            myAidlInterface.call();
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
    
    

        }
    };

    private void bindService() {
    
    
        // 调用 bindService
        Intent intent = new Intent(this, MyService.class);
        bindService(intent, serviceConnection, BIND_AUTO_CREATE);
    }

  • 总体流程图
    在这里插入图片描述

  • bindService() 流程

    @Override
    public boolean bindService(Intent service, ServiceConnection conn,
            int flags) {
    
    
        warnIfCallingFromSystemProcess();
        return bindServiceCommon(service, conn, flags, mMainThread.getHandler(), getUser());
    }
  • bindServiceCommon()
    private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, Handler
            handler, UserHandle user) {
    
    
        IServiceConnection sd;
    
        if (mPackageInfo != null) {
    
    
        	// 根据一个 ServiceConnection 生成一个 IServiceConnection;
        	// 因为 ServiceConnection 只是一个普通的接口,无法进行跨进程传输。所以通过 ServiceConnection 生成了一个 binder 对象
            sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);
        } 
        try {
    
    
            IBinder token = getActivityToken();
            // 通过上面为ServiceConnection生成的  binder 对象,生成了 IServiceConnection 传入给 AMS 的 bindeService
            int res = ActivityManager.getService().bindService(
                mMainThread.getApplicationThread(), getActivityToken(), service,
                service.resolveTypeIfNeeded(getContentResolver()),
                sd, flags, getOpPackageName(), user.getIdentifier());
            return res != 0;
    }

bindServiceCommon() 先通过 getServiceDispatcher() 函数把 ServiceConnection 对象生成了一个 IServiceConnection 的 binder 对象,方便跨进程传输,IServiceConnection 引用了 ServiceConnection,所以可以跨进程调用。然后将 IServiceConnection 作为参数,调用了 AMS 的 bindService() 函数。

  • getServiceDispatcher()
	// 入参传入了 ServiceConnection 返回值是一个 IServiceConnection 
    public final IServiceConnection getServiceDispatcher(ServiceConnection c,
            Context context, Handler handler, int flags) {
    
    
        synchronized (mServices) {
    
    
            LoadedApk.ServiceDispatcher sd = null;
         	// 先从 mServices 中获取ArrayMap 
            ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context);
            if (map != null) {
    
    
               	// 如果存在则尝试获取一下 看看是否创建过
                sd = map.get(c);
            }
            if (sd == null) {
    
    
            	// 如果 ServiceDispatcher == null 则创建一个对象出来
                sd = new ServiceDispatcher(c, context, handler, flags);
	            // 如果 map 也为 null 则创建一个 map 缓存数据添加到 mServices 中
                if (map == null) {
    
    
                    map = new ArrayMap<>();
                    mServices.put(context, map);
                }
                map.put(c, sd);
            } else {
    
    
                sd.validate(context, handler);
            }
            // sd.getIServiceConnection(); 就是生成 ServiceDispatcher 对象中的 binder 对象。
            return sd.getIServiceConnection();
        }
    }

  • ServiceDispatcher 对象
        ServiceDispatcher(ServiceConnection conn,
                Context context, Handler activityThread, int flags) {
    
    
            mIServiceConnection = new InnerConnection(this);
            mConnection = conn;
            mContext = context;
            mActivityThread = activityThread;
            // ...
        }
  • InnerConnection 类,它是一个 IServiceConnection.Stub 可以跨进程传递
        private static class InnerConnection extends IServiceConnection.Stub {
    
    
            final WeakReference<LoadedApk.ServiceDispatcher> mDispatcher;

            InnerConnection(LoadedApk.ServiceDispatcher sd) {
    
    
                mDispatcher = new WeakReference<LoadedApk.ServiceDispatcher>(sd);
            }

            public void connected(ComponentName name, IBinder service, boolean dead)
                    throws RemoteException {
    
    
                LoadedApk.ServiceDispatcher sd = mDispatcher.get();
                if (sd != null) {
    
    
                    sd.connected(name, service, dead);
                }
            }
        }

InnerConnection 传入了 ServiceDispatcher 对象,并设置了成员变量对他进行弱引用,当AMS 调用 connected 方法,mDispatcher 后去到 ServiceDispatcher ,然后调用 connected 方法。

  • sd.connected(name, service, dead);
        public void connected(ComponentName name, IBinder service, boolean dead) {
    
    
            if (mActivityThread != null) {
    
    
            	// 最后也会走 doConnected() 
                mActivityThread.post(new RunConnection(name, service, 0, dead));
            } else {
    
    
                doConnected(name, service, dead);
            }
        }
  • doConnected(name, service, dead);
       public void doConnected(ComponentName name, IBinder service, boolean dead) {
    
    
            ServiceDispatcher.ConnectionInfo old;
            ServiceDispatcher.ConnectionInfo info;
            synchronized (this) {
    
    
            	// 缓存中取 ServiceDispatcher.ConnectionInfo
                old = mActiveConnections.get(name);
                if (old != null && old.binder == service) {
    
    
                // 如果缓存过 则直接 return 防止 onServiceConnected() 重复调用
                    return;
                }
                // service != null 代表绑定上了
                if (service != null) {
    
    
                	// 创建 ConnectionInfo 对象
                    info = new ConnectionInfo();
                    info.binder = service;
                    	//。。。	
                    try {
    
    
                       // 添加到缓存
                        mActiveConnections.put(name, info);
                    } catch (RemoteException e) {
    
    
                        // This service was dead before we got it...  just
                        // don't do anything with it.
                        mActiveConnections.remove(name);
                        return;
                    }
                } else {
    
    
                // 如果 service == null 代表已经断开 直接 清除缓存
                    mActiveConnections.remove(name);
                }
            }
            
                if (old != null) {
    
    
                	// 这里面是代表 内部原理是 如果 binder 对象挂了 就会回调 onServiceDisconnected ,所以除了系统回收 要不然一般也收不到 onServiceDisconnected() 的回调
                    old.binder.unlinkToDeath(old.deathMonitor, 0);
                }
            // If there was an old service, it is now disconnected.
            if (old != null) {
    
    
            	// 如果绑定过 old 但是 old.binder != service
            	// 那么上面没有 return 到,代表已经断开了 直接 onServiceDisconnected 
            	// 基本上这种情况 onServiceDisconnected 方法也接收不到;
                mConnection.onServiceDisconnected(name);
            }
            // If there is a new viable service, it is now connected.
            if (service != null) {
    
    
            	// 绑定调用 onServiceConnected
                mConnection.onServiceConnected(name, service);
            } 
        }

在这里插入图片描述
IServiceConnection 和 ServiceConnection 并不是一对一的关系;一个 Context 和 一个 ServiceConnection 共同构成一个数据和 ServiceConnection关联,意思就是 同一个 ServiceConnection ,用不同的 Context 绑定的话会对应不同的 IServiceConnection;同样的 同一个 Context 绑定不同的 ServiceConnection 也是不同的 IServiceConnection。

  • 接下来看看 ActivityManager.getService().bindService() 到底是怎么绑定的
    public int bindService(IApplicationThread caller, IBinder token, Intent service,
            String resolvedType, IServiceConnection connection, int flags, String callingPackage,
            int userId) throws TransactionTooLargeException {
    
    
        synchronized(this) {
    
    
            return mServices.bindServiceLocked(caller, token, service,
                    resolvedType, connection, flags, callingPackage, userId);
        }
    }

bindServiceLocked()

    int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,
            String resolvedType, final IServiceConnection connection,...){
    
    
        if ((flags&Context.BIND_AUTO_CREATE) != 0) {
    
    
        	// 这个方法就是创建service的
			bringUpServiceLocked(s, service.getFlags(), callerFg, false, permissionsReviewRequired)
		}
		// 如果已经准备好了 并且已经报告给了AMS 
		if (s.app != null && b.intent.received) {
    
    
			// 直接返回给应用端
			c.conn.connected(s.name, b.intent.binder, false);
		} else if (!b.intent.requested) {
    
    
		//	 去请求 AMS
           requestServiceBindingLocked(s, b.intent, callerFg, false);
        }
	}

bringUpServiceLocked() 这个函数上面 startService 的时候已经讲过了。区别是 bindeService 不会触发 onStartCommond() 回调。 那么 看看上面方法中的 requestServiceBindingLocked() 函数

  • requestServiceBindingLocked()
    private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i,
            boolean execInFg, boolean rebind) throws TransactionTooLargeException {
    
    
            // 先判断 service 是否启动了
        if (r.app == null || r.app.thread == null) {
    
    
            // If service is not currently running, can't yet bind.
            return false;
        }
        // 判断是否绑定了 binder 对象  或者 是否触发了 rebind ;并且 需要 i.apps.size() > 0 代表当前有应用需要绑定
        if ((!i.requested || rebind) && i.apps.size() > 0) {
    
    
            try {
    
    
                r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,
                        r.app.repProcState);
            }
        }
        return true;
    }

  • 调用应用端 r.app.thread.scheduleBindService() 最终会通过 handler 调用到 handleBindService()
    private void handleBindService(BindServiceData data) {
    
    
        Service s = mServices.get(data.token);
        if (DEBUG_SERVICE)
            Slog.v(TAG, "handleBindService s=" + s + " rebind=" + data.rebind);
        if (s != null) {
    
    
            try {
    
    
                data.intent.setExtrasClassLoader(s.getClassLoader());
                data.intent.prepareToEnterProcess();
                try {
    
    
                	// 通过判断传回来的数据判断 onBind 还是 onRebind
                    if (!data.rebind) {
    
    
                        IBinder binder = s.onBind(data.intent);
                        // 通过 binder 调用 发布到 AMS
                        ActivityManager.getService().publishService(
                                data.token, data.intent, binder);
                    } else {
    
    
                        s.onRebind(data.intent);
                        ActivityManager.getService().serviceDoneExecuting(
                                data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
                    }
                    ensureJitEnabled();
                }
            } 
        }
    }
  • AMS 的 publishService() 会调用到 mServices.publishServiceLocked((ServiceRecord)token, intent, service);
   void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {
    
    
        final long origId = Binder.clearCallingIdentity();
        try {
    
    
            if (r != null) {
    
    
                Intent.FilterComparison filter
                        = new Intent.FilterComparison(intent);
                        // 通过 intent 先找到 IntentBindRecord 对象
                IntentBindRecord b = r.bindings.get(filter);
                if (b != null && !b.received) {
    
    
                    b.binder = service;// 保存 binder 对象
                    b.requested = true; // 表示是否请求过 bidner 对象
                    b.received = true; // 表示是否已经收到 binder 对象了
                    // for 循环找到所有匹配的 对象 调用 connected 把binder 对象返回给应用端
                    for (int conni=r.connections.size()-1; conni>=0; conni--) {
    
    
                        ArrayList<ConnectionRecord> clist = r.connections.valueAt(conni);
                        for (int i=0; i<clist.size(); i++) {
    
    
                            ConnectionRecord c = clist.get(i);
                            if (!filter.equals(c.binding.intent.intent)) {
    
    
                                continue;
                            }
                          
                            try {
    
    
                                c.conn.connected(r.name, service, false);
                            } catch (Exception e) {
    
    
                                Slog.w(TAG, "Failure sending service " + r.name +
                                      " to connection " + c.conn.asBinder() +
                                      " (in " + c.binding.client.processName + ")", e);
                            }
                        }
                    }
                }

                serviceDoneExecutingLocked(r, mDestroyingServices.contains(r), false);
            }
        } finally {
    
    
            Binder.restoreCallingIdentity(origId);
        }
    }

onRebind() 什么时候调用的

  • bindServiceLocked() 中有一行代码
    int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,...){
    
    
		// service 已经启动 并且已经接收到了 binder 对象
		if (s.app != null && b.intent.received) {
    
    
				// intent 下只有一个 进程绑定  && doRebind 参数为 true
                if (b.intent.apps.size() == 1 && b.intent.doRebind) {
    
    
                	// 最后一个参数为 true 表示要调用 onRebind
                    requestServiceBindingLocked(s, b.intent, callerFg, true);
                }
		}
}

doRebind 参数和unbindServiceLocked 有关

    boolean unbindServiceLocked(IServiceConnection connection) {
    
    
        IBinder binder = connection.asBinder();
     	//通过 binder 取出 ConnectionRecord 列表
        ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
    
        try {
    
    
            while (clist.size() > 0) {
    
    
                ConnectionRecord r = clist.get(0);
                // 依次调用 removeConnectionLocked 函数
                removeConnectionLocked(r, null, null);
                if (clist.size() > 0 && clist.get(0) == r) {
    
    
                    clist.remove(0);
                }
            }
        } 
        return true;
    }
  • removeConnectionLocked()
    void removeConnectionLocked(
    	// 如果Service还在 并且binde的 已经没有了进程来bind了
		if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
                    && b.intent.hasBound) {
    
    
                try {
    
    
                    // 则 Service 执行 scheduleUnbindService 回调
                    s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
                }
            }


	}
  • handleUnbindService()
    private void handleUnbindService(BindServiceData data) {
    
    
        Service s = mServices.get(data.token);
        if (s != null) {
    
    
            try {
    
    
                data.intent.setExtrasClassLoader(s.getClassLoader());
                data.intent.prepareToEnterProcess();
               	// 一般返回false 除非重写这个方法
                boolean doRebind = s.onUnbind(data.intent);
                try {
    
    
                    if (doRebind) {
    
    
                        ActivityManager.getService().unbindFinished(
                                data.token, data.intent, doRebind);
                    } else {
    
    
                        ActivityManager.getService().serviceDoneExecuting(
                                data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
                    }
                }
            } 
        }
    }

当没有应用还在bindService以后,调用 ActivityManager.getService().unbindFinished() 的话内部会把 doRebind 属性设置为 true ,那么下次再调用 bindService 的时候会执行 onRebind() 函数

猜你喜欢

转载自blog.csdn.net/ldxlz224/article/details/127504343
今日推荐