Service的bindService和unbindService的处理流程(分析源码)

本文深入解析Android中Service的bindService和unbindService处理流程,从AMS角度出发,探讨目标进程如何响应绑定请求,如何处理解绑请求,并分析Service进程中的数据结构,同时指出一些需要注意的问题,如onBind返回null的影响,Service销毁后的处理等。
摘要由CSDN通过智能技术生成

AMS处理bindService请求:

ActiveServices#bindServiceLocked

bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,
            String resolvedType, final IServiceConnection connection, int flags,
            String callingPackage, final int userId){
        ServiceLookupResult res =
            retrieveServiceLocked(service, resolvedType, callingPackage, Binder.getCallingPid(),
                    Binder.getCallingUid(), userId, true, callerFg, isBindExternal);//创建一个ServiceRecord

ServiceRecord s = res.record;
                    
AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);//如果没有则创建一个。从IntentBindRecord到AppBindRecord,类似建文件夹的mkdir -r 命令,如果不存在,就按路径递归创建
ConnectionRecord c = new ConnectionRecord(b, activity,
                    connection, flags, clientLabel, clientIntent);    //创建ConnectionRecord

b.connections.add(c);    //将ConnectionRecord加入AppBindRecord                
            
if ((flags&Context.BIND_AUTO_CREATE) != 0) {
     if (bringUpServiceLocked(s, service.getFlags(), callerFg, false,
                        permissionsReviewRequired) != null) {//如果r.app != null && r.app.thread != null成立,则bringUpServiceLocked会返回null,最后就不会触发return 0,代码继续往下走
                    return 0;
                }
            }    
if (s.app != null && b.intent.received) {

if (s.app != null && b.intent.received) {
                // Service is already running, so we can immediately
                // publish the connection.

//这种情况publishServiceLocked中不会去调用IServiceConnection#connected,所以要在这里调用
                    c.conn.connected(s.name, b.intent.binder);
              
       if (b.intent.apps.size() == 1 && b.intent.doRebind) {
                    requestServiceBindingLocked(s, b.intent, callerFg, true);//如果r.bindings不为null,则会触发scheduleBindService
                }
            }
else if (!b.intent.requested) {
                requestServiceBindingLocked(s, b.intent, callerFg, false);
            }


            
            }

ActiveServices#retrieveServiceLocked()

retrieveServiceLocked(){
ResolveInfo rInfo = AppGlobals.getPackageManager().resolveService(service,
                        resolvedType, ActivityManagerService.STOCK_PM_FLAGS
                                | PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
                        userId);
                        
ComponentName name = new ComponentName(
                        sInfo.applicationInfo.packageName, sInfo.name);                        
                        
r = new ServiceRecord(mAm, ss, name, filter, sInfo, callingFromFg, res);
return new ServiceLookupResult(r, null);
}

 

ActiveServices#bringUpServiceLocked

ActiveServices#bringUpServiceLocked{
//如果r.app不为null说明调用过了realStartServiceLocked,如果r.app.thread != null,则目标进程已经起来了
        if (r.app != null && r.app.thread != null) {
            sendServiceArgsLocked(r, execInFg, false);
            return null;
        }
        
final String procName = r.processName;

 ProcessRecord app;
 
 app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
 
 
 realStartServiceLocked(r, app, execInFg);
 }

 

ActiveServices#realStartServiceLocked

 realStartServiceLocked(ServiceRecord r,
            ProcessRecord app, boolean execInFg){
//调用scheduleCreateService()的地方在ActiveServices#realStartServiceLocked.
app.thread.scheduleCreateService()
 r.app = app;//为ServiceRecord设置ProcessRecord,所以如果r.app不为null,则证明来过这个方法,即已经调用了scheduleCreateService。
 
 requestServiceBindingsLocked(ServiceRecord r, boolean execInFg);//该方法会看有没有调用bindService,如果有,就调用scheduleBindService
 
 sendServiceArgsLocked(ServiceRecord r, boolean execInFg,    //该方法会去看有没有调用过startService,如果有,就调用scheduleServiceArgs
            boolean oomAdjusted);
            }

 

 


目标进程接收到绑定请求:  

        
handleBindService(BindServiceData data)

handleBindService(BindServiceData data){

if (!data.rebind) {
                        IBinder binder = s.onBind(data.intent);
                        ActivityManagerNative.getDefault().publishService(
           
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值