美文网首页
Android bindService流程分析

Android bindService流程分析

作者: 晴天12345 | 来源:发表于2017-10-21 20:35 被阅读192次

1.1 Service相关数据结构

Service相关数据结构

1.2 Service Bind & Unbind流程

BindService相关流程图

2.1 bindServiceLocked 解析

bindServiceLocked
  • 通过retrieveServiceLocked(), 根据用户传递进来Intent来检索相对应的服务
  • 通过retrieveAppBindingLocked()。创建AppBindRecord对象记录着当前ServiceRecord, intent以及发起方的进程信息。
  • 通过bringUpServiceLocked()拉起目标服务;

2.2 retrieveServiceLocked

查找相应的servicerecord,如果没有则创建;

2.3 retrieveAppBindingLocked

创建AppBindRecord对象;
数据流程

servicerecord -> appbindrecord -> connectionrecord --save->ActiveServices

2.4 bringUpServiceLocked

作用:拉起servicestartService一致;

  • bringUpServiceLocked 中根据app ?= null , 调用startProcessLocked启动新进程;
  • realStartServiceLocked 中根据传递的命令调用CreateService BindService UnBindeService
  • RunConnection 分发命令,调用客户端onServiceConnect & onServiceDisConnect

2.5 绑定service解析

handleBindService 最终调用service onBind,获得服务端返回的binder;通过pulishService发布到AMS

  1. AMSservice相关的执行方法被委托给ActiveServicesActiveServices根据ServiceRecord找到ConnectionRecord,然后调用对应IServiceConnectionconnected方法;
  2. IServiceConnection.Stub.Proxy 会调用servicedispatcherconnected方法,
  3. sdconnected中,会往主线程post RunConnection对象,RunConnection是线程对象,run方法中会调用sddoConnected方法,
  4. 由于sd在创建保存了ServiceConnection对象,所以也就调用了Client的的conn对象,并传递了service端返回的binder
  5. ConnectionRecord创建于ActivieServices中,被添加到mServiceConnections中,mServiceConnections根据connection.asBinder,记录了不同servicerecord的连接;

2.6 PublishServie

调用service onBind之后,通过publish向AMS发布该service,目的是让Client通过AMS获取该service Binder

2.7 ActiveServices::publishServiceLocked

void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {
    final long origId = Binder.clearCallingIdentity();
    try {
        if (r != null) {
            Intent.FilterComparison filter = new Intent.FilterComparison(intent);
            IntentBindRecord b = r.bindings.get(filter);
            if (b != null && !b.received) {
                b.binder = service;
                b.requested = true;
                b.received = true;
                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;
                        }
                        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Publishing to: " + c);
                        try {
                            c.conn.connected(r.name, service); // 调用ServiceConnection connected
                        } catch (Exception e) {
                        }
                    }
                }
            }

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

AMS遍历找到ConnectionRecord

相关文章

网友评论

      本文标题:Android bindService流程分析

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