Android bindService流程一

752 阅读1分钟

启动service之bindService

bindService就是将activity和service进行绑定,可以拿到service对象,也可以根据需要在合适的时机解绑service,让activity和service的生命周期有联系,下面分析一下bind的过程 step1:ContextImp#bindService

public boolean bindService(Intent service, ServiceConnection conn,  int flags) {
        // 传入mMainThread.getHandler()
        return bindServiceCommon(service, conn, flags, mMainThread.getHandler(), getUser());
}

private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags, Handler
        handler, UserHandle user) {
    // Keep this in sync with DevicePolicyManager.bindDeviceAdminServiceAsUser.
    IServiceConnection sd;
    // serviceconnection不可以为空
    if (conn == null) {
        throw new IllegalArgumentException("connection is null");
    }
    if (mPackageInfo != null) {
        // step2 获取servicedispatcher对象
        sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags);
    } 
    validateServiceIntent(service);
    ...
        IBinder token = getActivityToken();
        ...
        service.prepareToLeaveProcess(this);
        // step3 调用到ams的bindservice
        int res = ActivityManager.getService().bindService(
            mMainThread.getApplicationThread(), getActivityToken(), service,
            service.resolveTypeIfNeeded(getContentResolver()),
            sd, flags, getOpPackageName(), user.getIdentifier());
        
        return res != 0;
}

step2 : 获取ServiceDispatcher mPackageInfo是LoadedApk类型

    public final IServiceConnection getServiceDispatcher(ServiceConnection c,
            Context context, Handler handler, int flags) {
        synchronized (mServices) {
            LoadedApk.ServiceDispatcher sd = null;
            // mServices是loadedapk中的属性
            ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher> map = mServices.get(context);
            if (map != null) {
                sd = map.get(c);
            }
            if (sd == null) {
                sd = new ServiceDispatcher(c, context, handler, flags);
                if (map == null) {
                    map = new ArrayMap<>();
                    mServices.put(context, map);
                }
                map.put(c, sd);
            } else {
                sd.validate(context, handler);
            }
            // 返回的是IServiceConnection类型的binder对象
            return sd.getIServiceConnection();
        }
    }
private final ArrayMap<Context, ArrayMap<ServiceConnection, LoadedApk.ServiceDispatcher>> mServices = new ArrayMap<>();

上面的代码就是在本地查找是否有conn对应的ServiceDispatcher对象,如果没有的话就创建ServiceDispatcher,并创建conn和ServiceDispatcher的映射关系map,再以context为key,保存到mServices。 最后返回的是sd.getIServiceConnection()

IServiceConnection getIServiceConnection() {
     //mIServiceConnection是的成员属性 在构造函数中赋值
     return mIServiceConnection;
}

static final class ServiceDispatcher {
        private final ServiceDispatcher.InnerConnection mIServiceConnection;

        ServiceDispatcher(ServiceConnection conn,
                Context context, Handler activityThread, int flags) {
            //mIServiceConnection 是InnerConnection类型
            mIServiceConnection = new InnerConnection(this);
            mConnection = conn;
            mContext = context;
            mActivityThread = activityThread;
        }
        // 实现了IServiceConnection.Stub的binder对象,
        private static class InnerConnection extends IServiceConnection.Stub {
            // 持有ServiceDispatcher的弱引用
            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);
                }
            }
        }

那么这里就获取到了ServiceDispatcher的binder对象。回到bindservice的step3,分析调用AMS的bindService