Service源码分析系列(二):bindService流程分析

来源:互联网 发布:鉴别声音的软件 编辑:程序博客网 时间:2024/06/14 04:42

Service源码分析系列(二):bindService流程分析

之前一篇分析了Service启动流程中的startService,这篇来分析Service的绑定,bindService。

Service源码分析系列(一):startService


Activity

本文从Activity的startService(Intent service)入手分析

  • 先看看在Activity中怎么绑定一个Service(常规做法),代码如下
private ServiceConnection conn = new ServiceConnection() {          @Override          public void onServiceConnected(ComponentName name, IBinder service) {             // 绑定成功           ...        }          @Override          public void onServiceDisconnected(ComponentName name) {           // 绑定结束            ...          }   private void f(){        Intent intent = new Intent(this, XXXService.class);        // bindService的具体实现在ContextImpl        // BIND_AUTO_CREATE参数具体使用的代码 ActivityServices???        bindService(intent,conn,BIND_AUTO_CREATE);    }

ContextImpl

  • ContextImpl的bindService,bindService最终调用bindServiceCommon,代码如下
 @Override    public boolean bindService(Intent service, ServiceConnection conn,            int flags) {        // mMainThread.getHandler(),传入的handle是主线程的Handle!        return bindServiceCommon(service, conn, flags, mMainThread.getHandler(),                Process.myUserHandle());    }
 private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, Handler            handler, UserHandle user) {        IServiceConnection sd;        ...        if (mPackageInfo != null) {            // 第一步,将传入的ServiceConnection转化为IServiceConnection返回,这不下面具体分析            // mPackgeInfo是LoadedApk            sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);        }        // 5.0以后禁止Service隐式绑定,判断和startService一样        validateServiceIntent(service);        try {            IBinder token = getActivityToken();            ...            // 第二步,Binder调用AMS的bindService方法,下面具体分析            int res = ActivityManagerNative.getDefault().bindService(                mMainThread.getApplicationThread(), getActivityToken(), service,                service.resolveTypeIfNeeded(getContentResolver()),                sd, flags, getOpPackageName(), user.getIdentifier());            return res != 0;        }         ...    }    }

LoadedApk

Local state maintained about a currently loaded .apk.
LoadedApk对象是APK文件在内存中的表示。 Apk文件的相关信息,诸如Apk文件的代码和资源,甚至代码里面的Activity,Service等组件的信息我们都可以通过此对象获取。

  • 第一步调用LoadedApk的getServiceDispatcher,将ServiceConnection转化为能在进程间传递的Binder接口——IServiceConnection,因为Service的绑定很有可能是跨进程的。
  • IServiceConnection的实现类是ServiceDispatcher.InnerConnection,ServiceDispatcher里面保存了当前的ServiceConnection和相应的InnerConnection。
public final IServiceConnection getServiceDispatcher(ServiceConnection c,            Context context, Handler handler, int flags) {        synchronized (mServices) {            LoadedApk.ServiceDispatcher sd = null;            // private final ArrayMap<Context,            // ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>> mServices            // 根据当前的Context获取ArrayMap<ServiceConnection,            // LoadedApk.ServiceDispatcher>            ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context);            if (map != null) {                // 如果存在,尝试根据当前的ServiceConnection获取ServiceDispatcher                sd = map.get(c);            }            if (sd == null) {                // 如果与ServiceConnection对应的ServiceDispatcher不存在,创建一个保存了当前ServiceConnection的ServiceDispatcher对象,                // 并将之前传入的主线的Handle保存,同时创建一个InnerConnection对象保存                sd = new ServiceDispatcher(c, context, handler, flags);                if (map == null) {                    map = new ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>();                    mServices.put(context, map);                }                // 将该ServiceConnection与ServiceDispatcher关系保存                map.put(c, sd);            } else {                // 如果最开始就获取到ServiceDispatcher,比如多次bindService,                // 就会调用ServiceDispatcher的validate判断此次bindService是否合法                // validate的判断逻辑比较简单,1.判断当前的context是否和之前bindService的一样 2.判断当前handler是否是主线程的handle                // 以上两个条件都满足的情况下正常执行,反之抛出相应的异常                sd.validate(context, handler);            }            return sd.getIServiceConnection();        }    }

ActivityManagerService

public abstract class ActivityManagerNative extends Binder implements IActivityManager
public interface IActivityManager extends IInterface
从中可以看出ActivityManagerNative是一个Binder类,Activity的启动已经通过Binder调用转交到系统服务中了。
IActivityManager Binder具体实现是ActivityManagerService,最终调用到ActivityManagerService的bindService
调用进入ActivityManagerService的进程

  • ActivityManagerService的bindService代码如下
 public int bindService(IApplicationThread caller, IBinder token, Intent service,            String resolvedType, IServiceConnection connection, int flags, String callingPackage,            int userId) throws TransactionTooLargeException {        ...        synchronized(this) {            // 调用ActiveServices的bindServiceLocked方法            return mServices.bindServiceLocked(caller, token, service,                    resolvedType, connection, flags, callingPackage, userId);        }    }

ActiveServices

ActiveServices是AMS中专门抽出来管理Service活动的类,包括启动、绑定等。

  • ActiveServices的bindServiceLocked调用了bringUpServiceLocked
  • bringUpServiceLocked调用了realStartServiceLocked
  • realStartServiceLocked代码如下
private final void realStartServiceLocked(ServiceRecord r,            ProcessRecord app, boolean execInFg) throws RemoteException {       ...        try {            ...            // 第一步,调用ApplicationThread的scheduleCreateService方法,之后会实例化Service并调用Service的onCreate方法,            // 不会调用onStartCommand,详见Service详解及源码分析系列(一):startService            app.thread.scheduleCreateService(r, r.serviceInfo,                    mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),                    app.repProcState);        }         ...        // 第二步,调用requestServiceBindingsLocked        requestServiceBindingsLocked(r, execInFg);        updateServiceClientActivitiesLocked(app, null, true);        // 第三步,注意下面的注释!!,分析待补充        // If the service is in the started state, and there are no        // pending arguments, then fake up one so its onStartCommand() will        // be called.        if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {            r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),                    null, null));        }        // StartItem的taskRemoved如果是false的话,调用下面方法会调用Service的onStartCommand!!!        sendServiceArgsLocked(r, execInFg, true);        ...    }
  • 第一步,调用ApplicationThread的scheduleCreateService方法,之后会实例化Service并调用Service的onCreate方法,详见Service详解及源码分析系列(一):startService
  • 第二步调用requestServiceBindingsLocked,之后调用到requestServiceBindingLocked,代码如下
private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i,            boolean execInFg, boolean rebind) throws TransactionTooLargeException {       ...        if ((!i.requested || rebind) && i.apps.size() > 0) {            try {                ...                // 调用ApplicationThread的scheduleBindService方法                r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,                        r.app.repProcState);            }             ...        }        ...        return true;    }

ApplicationThread

IApplicationThread thread;
public interface IApplicationThread extends IInterface
public abstract class ApplicationThreadNative extends Binder implements IApplicationThread
ApplicationThreadNative的具体实现是ActivityThread中的ApplicationThread
ApplicationThread实现了许多Activity和Service 启动、暂停等有关的操作
调用进入应用程序的进程

  • 调用ApplicationThread的scheduleBindService,scheduleBindService通过mH发送一个H.BIND_SERVICE消息,mH收到该消息调用 handleBindService(BindServiceData data),代码如下
private void handleBindService(BindServiceData data) {       // 根据token获取Service token具体分析???        Service s = mServices.get(data.token);        if (s != null) {            try {                try {                    // rebind具体分析???                    if (!data.rebind) {                        // 调用Service的onBind,返回给客户端调用的Binder                        IBinder binder = s.onBind(data.intent);// 调用AMS的publishService,进而通知客户端连接成功???                        ActivityManagerNative.getDefault().publishService(                                data.token, data.intent, binder);                    } else {                        // onRebind???                        s.onRebind(data.intent);                  // ???      ActivityManagerNative.getDefault().serviceDoneExecuting(                                data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);                    }                    ensureJitEnabled();                }            }             ...        }    }
原创粉丝点击