Service绑定形式启动过程

来源:互联网 发布:恋夜秀场怎样抓取源码 编辑:程序博客网 时间:2024/05/20 08:00
一、绑定形式Service的使用
1)定义一个Service,注意重写onBind方法,返回一个IBinder对象

public class MyService extends Service {    public static final String LOG_TAG = "LOG_TAG";    private MyBinder mBinder = new MyBinder();    public class MyBinder extends Binder {        public MyService getService() {            return MyService.this;        }    }    @Override    public void onCreate() {        super.onCreate();        Log.d(LOG_TAG, "onCreate");    }    @Override    public int onStartCommand(Intent intent, int flags, int startId) {        Log.d(LOG_TAG, "onStartCommand");        return super.onStartCommand(intent, flags, startId);    }    @Nullable    @Override    public IBinder onBind(Intent intent) {        Log.d(LOG_TAG, "onBind");        return mBinder;    }    @Override    public boolean onUnbind(Intent intent) {        Log.d(LOG_TAG, "onUnbind");        return super.onUnbind(intent);    }    @Override    public void onDestroy() {        super.onDestroy();        Log.d(LOG_TAG, "onDestroy");    }}


2)注意在manifest中注册service

<service android:name=".MyService"/>
 

3)在Activity中bindService:

public class ServiceActivity extends AppCompatActivity {    private MyService mService;    // 定义ServiceConnection    private ServiceConnection conn = new ServiceConnection() {        @Override        public void onServiceConnected(ComponentName name, IBinder service) {            // 通过定义的Binder来获取Service实例来供使用            mService = ((MyService.MyBinder) service).getService();            Log.w(MyService.LOG_TAG, "Activity onServiceConnected");        }        @Override        public void onServiceDisconnected(ComponentName name) {            mService = null;            // 当Service被意外销毁时            Log.w(MyService.LOG_TAG, "Activity onServiceDisconnected");        }    };    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.empty_ayout);    }    @Override    protected void onResume() {        super.onResume();        // bindService        Intent intent = new Intent(this, MyService.class);        bindService(intent, conn, Context.BIND_AUTO_CREATE);        Log.w(MyService.LOG_TAG, "Activity bindService");    }    @Override    protected void onPause() {        super.onPause();        // 进行unbind        unbindService(conn);        Log.w(MyService.LOG_TAG, "Activity unbindService");    }}

二、Service绑定形式源码分析
1)ContextWrapper#bindService:

/** @path: \frameworks\base\core\java\android\content\ContextWrapper.java **/@Overridepublic boolean bindService(Intent service, ServiceConnection conn, int flags) {    // @value Context mBase;    return mBase.bindService(service, conn, flags);}
和启动形式相仿,接下来调用ContextImpl.bindService;


2) ContextImpl#bindService:

/** @path: \frameworks\base\core\java\android\app\ContextImpl.java**/@Overridepublic boolean bindService(Intent service, ServiceConnection conn, int flags) {    warnIfCallingFromSystemProcess();    return bindServiceCommon(service, conn, flags, Process.myUserHandle());}

3) ContextImpl#bindServiceCommon:

/** @path: \frameworks\base\core\java\android\app\ContextImpl.java**/private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags,                                  UserHandle user) {    IServiceConnection sd;    if (conn == null) {        throw new IllegalArgumentException("connection is null");    }    if (mPackageInfo != null) {        // 将ServiceConnection封装成为IServiceConnection        sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(),                mMainThread.getHandler(), flags);    } else {        throw new RuntimeException("Not supported in system context");    }    validateServiceIntent(service);    try {        IBinder token = getActivityToken();        if (token == null && (flags&BIND_AUTO_CREATE) == 0 && mPackageInfo != null                && mPackageInfo.getApplicationInfo().targetSdkVersion                < Build.VERSION_CODES.ICE_CREAM_SANDWICH) {            flags |= BIND_WAIVE_PRIORITY;        }        service.prepareToLeaveProcess();        // 调用bindService来绑定启动Service        int res = ActivityManagerNative.getDefault().bindService(                mMainThread.getApplicationThread(), getActivityToken(),                service, service.resolveTypeIfNeeded(getContentResolver()),                sd, flags, user.getIdentifier());        if (res < 0) {            throw new SecurityException(                    "Not allowed to bind to service " + service);        }        return res != 0;    } catch (RemoteException e) {        return false;    }}
代码中首先将ServiceConnection对象转化成为IServiceConnection。因为Service与客户端建立的连接,可能是跨进程的,系统在绑定Service过程中可能通过IServiceConnection来调用ServiceConnection中的onServiceConnection方法,该过程可能是跨进程的,IServiceConnection是个AIDL文件;

之后再通过ActivityManagerNative.getDefault().bindService来开始绑定Service操作。


先来看第一步,由于mPackageInfo的类型为LoadedApk;
final LoadedApk mPackageInfo;
3.1)LoadedApk#getServiceDispatcher:

/** @path: \frameworks\base\core\java\android\app\LoadedApk.java**/public final IServiceConnection getServiceDispatcher(ServiceConnection c, Context context, Handler handler, int flags) {    synchronized (mServices) {        ServiceDispatcher sd = null;        // 以ServiceConnection为关键字,将ServiceDispatcher与erviceConnection建立关联保存起来        // 还可以看到保存的ArrayMap最终会以Context为关键字保存在一个变量mServices中        /** @value :private final ArrayMap<Context, ArrayMap<ServiceConnection, ServiceDispatcher>> mServices                                 = new ArrayMap<Context, ArrayMap<ServiceConnection, ServiceDispatcher>>();**/        ArrayMap<ServiceConnection, ServiceDispatcher> map = mServices.get(context);        // 先尝试进行获取        if (map != null) {            sd = map.get(c);        }        // 如果已存在直接返回,未存在则进行创建        if (sd == null) {            // 创建一个新的ServiceDispatcher            sd = new ServiceDispatcher(c, context, handler, flags);            // 如果map为空,则创建一个ArrayMap并保存到mServices中            if (map == null) {                map = new ArrayMap<ServiceConnection, ServiceDispatcher>();                mServices.put(context, map);            }            // 将对应的ServiceConnection与ServiceDispatcher保存到一个map中            map.put(c, sd);        } else {            sd.validate(context, handler);        }        // 返回一个IServiceConnection类型        return sd.getIServiceConnection();    }}
方法中的参数:

ServiceConnection c  == 即Service中自定义的ServiceConnection对象

Context context         == 传入的为getOuterContext(),即mOuterContext,ContextImpl类型,指向一个Activity组件

Handler handler        == 传入参数为mMainThread.getHandler();

mMainThread的类型为ActivityThread:

final ActivityThread mMainThread;/** @path: \frameworks\base\core\java\android\app\ActivityThread.java**/final H mH = new H();final Handler getHandler() {    return mH;}
可以看到最终用来发送启动service消息到主线程的Handler H。

继续来看sd.getIServiceConnection();ServiceDispatcher是LoadedApk的内部类。

先来看ServiceDispatcher的构造函数:

3.2)LoadedApk#ServiceDispatcher#ServiceDispatcher:

/** @path: \frameworks\base\core\java\android\app\LoadedApk.java**/static final class ServiceDispatcher {    private final InnerConnection mIServiceConnection;    private final ServiceConnection mConnection;    private final Context mContext;    private final Handler mActivityThread;    private final ServiceConnectionLeaked mLocation;    private final int mFlags;    private static class InnerConnection extends IServiceConnection.Stub {        final WeakReference<ServiceDispatcher> mDispatcher;        InnerConnection(ServiceDispatcher sd) {            mDispatcher = new WeakReference<ServiceDispatcher>(sd);        }        public void connected(ComponentName name, IBinder service) throws RemoteException {            ServiceDispatcher sd = mDispatcher.get();            if (sd != null) {                sd.connected(name, service);            }        }    }        ServiceDispatcher(ServiceConnection conn, Context context, Handler activityThread, int flags) {        mIServiceConnection = new InnerConnection(this);        mConnection = conn;        mContext = context;        mActivityThread = activityThread;        mLocation = new ServiceConnectionLeaked(null);        mLocation.fillInStackTrace();        mFlags = flags;    }}
    可以看到InnerConnection继承了IServiceConnection.Stub,IServiceConnection是个aidl,因此将本地的ServiceConnection封装成为ServiceDispatcher#InnerConnection,可以用以进程间的通信。


3.3)LoadedApk#ServiceDispatcher#getIServiceConnection:

/** @path: \frameworks\base\core\java\android\app\LoadedApk.java**/static final class ServiceDispatcher {    private final InnerConnection mIServiceConnection;    IServiceConnection getIServiceConnection() {        return mIServiceConnection;    }}
getIServiceConnection逻辑较为简单,即是返回新创建的InnerConnection,因此sd的编译时类型为IServiceConnection,运行时类型为ServiceDispatcher.InnerConnection:


分析完ServiceConnection,下面接着分析ActivityManagerNative.getDefault().bindService,由前面得知ActivityManagerNative.getDefault()的类型为AMS的代理:ActivityManagerProxy;则下面调用的是ActivityManagerProxy.bindService;

4、ActivityManagerProxy#bindService:
调用:

ActivityManagerNative.getDefault().bindService(        mMainThread.getApplicationThread(), getActivityToken(),service, service.resolveTypeIfNeeded(getContentResolver()),sd, flags, user.getIdentifier());
源代码: 

/** @path:  \frameworks\base\core\java\android\app\ActivityManagerNative.java**/class ActivityManagerProxy implements IActivityManager {    public int bindService(IApplicationThread caller, IBinder token,                           Intent service, String resolvedType, IServiceConnection connection,                           int flags, int userId) throws RemoteException {        Parcel data = Parcel.obtain();        Parcel reply = Parcel.obtain();        data.writeInterfaceToken(IActivityManager.descriptor);        data.writeStrongBinder(caller != null ? caller.asBinder() : null);        data.writeStrongBinder(token);        service.writeToParcel(data, 0);        data.writeString(resolvedType);        // 可以看到将ServiceConnection写入到data中,发送给AMS        data.writeStrongBinder(connection.asBinder());        data.writeInt(flags);        data.writeInt(userId);        // 发送BIND_SERVICE_TRANSACTION IPC通信请求        mRemote.transact(BIND_SERVICE_TRANSACTION, data, reply, 0);        reply.readException();        int res = reply.readInt();        data.recycle();        reply.recycle();        return res;    }}
将前面获取到的sd以Binder方式发送给AMS,并发送 BIND_SERVICE_TRANSACTION IPC通信请求。

接下来到ActivityManagerNative中去处理:


5、ActivityManagerNative#onTransact:

/** @path:  \frameworks\base\core\java\android\app\ActivityManagerNative.java**/public abstract class ActivityManagerNative extends Binder implements IActivityManager {    @Override    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)            throws RemoteException {        switch (code) {            case BIND_SERVICE_TRANSACTION: {                data.enforceInterface(IActivityManager.descriptor);                IBinder b = data.readStrongBinder();                IApplicationThread app = ApplicationThreadNative.asInterface(b);                IBinder token = data.readStrongBinder();                Intent service = Intent.CREATOR.createFromParcel(data);                String resolvedType = data.readString();                b = data.readStrongBinder();                int fl = data.readInt();                int userId = data.readInt();                IServiceConnection conn = IServiceConnection.Stub.asInterface(b);                // 处理IPC请求函数                int res = bindService(app, token, service, resolvedType, conn, fl, userId);                reply.writeNoException();                reply.writeInt(res);                return true;            }        }    }}
接下来使用ActivityManagerNative的子类ActivityManagerService来具体处理该应用请求:


6、ActivityManagerService#bindService:

/** @path: \frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java**/public int bindService(IApplicationThread caller, IBinder token,                       Intent service, String resolvedType,                       IServiceConnection connection, int flags, int userId) {    enforceNotIsolatedCaller("bindService");    // Refuse possible leaked file descriptors    if (service != null && service.hasFileDescriptors() == true) {        throw new IllegalArgumentException("File descriptors passed in Intent");    }    synchronized(this) {        return mServices.bindServiceLocked(caller, token, service, resolvedType,                connection, flags, userId);    }}
和启动形式一样,最后交给ActiveServices去处理;


7、ActiveServices#bindServiceLocked:

/** @path: \frameworks\base\services\core\java\com\android\server\am\ActiveServices.java**/int bindServiceLocked(IApplicationThread caller, IBinder token,                      Intent service, String resolvedType,                      IServiceConnection connection, int flags, int userId) {    // 该ProcessRecord描述的是请求绑定该Service组件的Activity组件所运行的应用进程    final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);    // 获得ActivityRecord用来描述该Activity组件    ActivityRecord activity = null;    if (token != null) {        activity = ActivityRecord.isInStackLocked(token);        if (activity == null) {            return 0;        }    }    .....    // 将待启动的Service组件信息封装成ServiceLookupResult    ServiceLookupResult res =            retrieveServiceLocked(service, resolvedType,                    Binder.getCallingPid(), Binder.getCallingUid(), userId, true, callerFg);    .....    // ServiceRecord用来记录该Service组件的相关信息    ServiceRecord s = res.record;    final long origId = Binder.clearCallingIdentity();    try {        .....        // 获得AppBindRecord,表示service对应的组件绑定在callerApp所描述的应用进程中        AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);                // 用来描述activity对应的Activity组件通过connection绑定到b(AppBindRecord)所对应的应用进程中的Service组件        ConnectionRecord c = new ConnectionRecord(b, activity,                connection, flags, clientLabel, clientIntent);                IBinder binder = connection.asBinder();        // 因为该Service组件可能被同一应用中的多个Activity组件使用同一个connection来绑定        // 因此该Binder可能对应多个ConnectionRecord对象        ArrayList<ConnectionRecord> clist = s.connections.get(binder);        if (clist == null) {            clist = new ArrayList<ConnectionRecord>();            s.connections.put(binder, clist);        }        clist.add(c);        b.connections.add(c);        if (activity != null) {            if (activity.connections == null) {                activity.connections = new HashSet<ConnectionRecord>();            }            activity.connections.add(c);        }        b.client.connections.add(c);        if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {            b.client.hasAboveClient = true;        }        if (s.app != null) {            updateServiceClientActivitiesLocked(s.app, c, true);        }        clist = mServiceConnections.get(binder);        if (clist == null) {            clist = new ArrayList<ConnectionRecord>();            mServiceConnections.put(binder, clist);        }        clist.add(c);        if ((flags&Context.BIND_AUTO_CREATE) != 0) {            s.lastActivity = SystemClock.uptimeMillis();            // bringUpServiceLocked启动Service组件            if (bringUpServiceLocked(s, service.getFlags(), callerFg, false) != null) {                return 0;            }        }        ......    } finally {    }    return 1;}

先来看一个函数:retrieveAppBindingLocked:

public AppBindRecord retrieveAppBindingLocked(Intent intent,        ProcessRecord app) {    Intent.FilterComparison filter = new Intent.FilterComparison(intent);    IntentBindRecord i = bindings.get(filter);    if (i == null) {        i = new IntentBindRecord(this, filter);        bindings.put(filter, i);    }    // 将ProcessRecord与Service组件建立起关联    AppBindRecord a = i.apps.get(app);    if (a != null) {        return a;    }    a = new AppBindRecord(this, i, app);    i.apps.put(app, a);    return a;}

Service组件的启动机制深入学习》一文中的分析知,接下来调用bringUpServiceLocked方法来启动Service组件,接着调用realStartServiceLocked在app所描述的进程中启动该Activity组件:


注意realStartServiceLocked中有一步:

8、ActiveServices#realStartServiceLocked:

/** @path: \frameworks\base\services\core\java\com\android\server\am\ActiveServices.java**/private final void realStartServiceLocked(ServiceRecord r,                                          ProcessRecord app, boolean execInFg) throws RemoteException {    ......    try {        ....        app.thread.scheduleCreateService(r, r.serviceInfo,                mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),                app.repProcState);        ....    } catch (DeadObjectException e) {    } finally {    }    ....    // 这里执行进行绑定操作    requestServiceBindingsLocked(r, execInFg);    ....}
可以看到通过scheduleCreateService启动Service组件之后,调用requestServiceBindingsLocked来执行绑定操作,由前面知启动方式的execInfg为false,即不需要绑定;

下面通过 scheduleCreateService启动Service组件的流程和Service组件的启动机制深入学习》中分析的启动流程相同;接下来分析Service组件启动之后,执行的绑定操作:


9、ActiveServices#requestBindingsLocked:

/** @path: \frameworks\base\services\core\java\com\android\server\am\ActiveServices.java**/private final void requestServiceBindingsLocked(ServiceRecord r, boolean execInFg) {    // 由前面知,r.bindings中保存了一系列Service组件和app之间的绑定关系    for (int i=r.bindings.size()-1; i>=0; i--) {        // 执行遍历,将Service绑定到这些ProcessRecord中        IntentBindRecord ibr = r.bindings.valueAt(i);        if (!requestServiceBindingLocked(r, ibr, execInFg, false)) {            break;        }    }}

10、 ActiveServices#requestBindingsLocked:

/** @path: \frameworks\base\services\core\java\com\android\server\am\ServiceRecord.java**/private final boolean requestServiceBindingLocked(ServiceRecord r,                                                  IntentBindRecord i, boolean execInFg, boolean rebind) {    if (r.app == null || r.app.thread == null) {        // If service is not currently running, can't yet bind.        return false;    }    // rebind参数用以标示是否需要重新绑定    if ((!i.requested || rebind) && i.apps.size() > 0) {        try {            bumpServiceExecutingLocked(r, execInFg, "bind");            r.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);            // 接下来调用scheduleBindService去绑定Service组件            r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,                    r.app.repProcState);            if (!rebind) {                i.requested = true;            }            i.hasBound = true;            i.doRebind = false;        } catch (RemoteException e) {            if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);            return false;        }    }    return true;}
代码逻辑较为简单,需要重新绑定或者i.apps中仍然有为执行完的绑定任务,都继续调用scheduleBindService来执行绑定任务;


r.app.thread的实际运行时类型为ApplicationThreadProxy。

11、 ApplicationThreadProxy#scheduleBindService:

/** @path: \frameworks\base\core\java\android\app\ApplicationThreadNative.java**/class ApplicationThreadProxy implements IApplicationThread {    public final void scheduleBindService(IBinder token, Intent intent, boolean rebind,                                          int processState) throws RemoteException {        Parcel data = Parcel.obtain();        data.writeInterfaceToken(IApplicationThread.descriptor);        data.writeStrongBinder(token);        intent.writeToParcel(data, 0);        data.writeInt(rebind ? 1 : 0);        data.writeInt(processState);        mRemote.transact(SCHEDULE_BIND_SERVICE_TRANSACTION, data, null,                IBinder.FLAG_ONEWAY);        data.recycle();    }}
发送一个 SCHEDULE_BIND_SERVICE_TRANSACTION类型的IPC请求;


12、ApplicationThreadNative#onTransact:

/** @path: \frameworks\base\core\java\android\app\ApplicationThreadNative.java**/public abstract class ApplicationThreadNative extends Binder        implements IApplicationThread {    @Override    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)            throws RemoteException {        switch (code) {            case SCHEDULE_BIND_SERVICE_TRANSACTION: {                data.enforceInterface(IApplicationThread.descriptor);                IBinder token = data.readStrongBinder();                Intent intent = Intent.CREATOR.createFromParcel(data);                boolean rebind = data.readInt() != 0;                int processState = data.readInt();                scheduleBindService(token, intent, rebind, processState);                return true;            }        }    }}
可以看到接下里调用子类ApplicationThread的scheduleBindService;


13:ApplicationThread#scheduleBindService:

/** @path: \frameworks\base\core\java\android\app\ActivityThread.java**/private class ApplicationThread extends ApplicationThreadNative {    public final void scheduleBindService(IBinder token, Intent intent,                                          boolean rebind, int processState) {        updateProcessState(processState, false);        BindServiceData s = new BindServiceData();        s.token = token;        s.intent = intent;        s.rebind = rebind;        sendMessage(H.BIND_SERVICE, s);    }}
类似得,通过H发送一个BIND_SERVICE请求,直接来看响应函数;


14、H:

/** @path: \frameworks\base\core\java\android\app\ActivityThread.java**/private class H extends Handler {    public static final int BIND_SERVICE            = 121;    void handleMessage(Message msg) {        switch (msg.what) {            case BIND_SERVICE:                Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind");                handleBindService((BindServiceData)msg.obj);                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);                break;        }    }    private void handleBindService(BindServiceData data) {        // data.token指向了一个ServiceRecord        // 由启动过程知,mServices保存了所有启动后的Service,这里通过data.token关键字进行获取        Service s = mServices.get(data.token);        if (s != null) {            try {                data.intent.setExtrasClassLoader(s.getClassLoader());                data.intent.prepareToEnterProcess();                try {                    if (!data.rebind) {                        // 可以看到这里就是自定义Service时重写的onBind函数                        IBinder binder = s.onBind(data.intent);                        // 继续通过publishService来实现                        ActivityManagerNative.getDefault().publishService(                                data.token, data.intent, binder);                    } else { // 调用rebind情况                        s.onRebind(data.intent);                        ActivityManagerNative.getDefault().serviceDoneExecuting(                                data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);                    }                    ensureJitEnabled();                } catch (RemoteException ex) {                }            } catch (Exception e) {                .......            }        }    }}
可以看到系统先根据 data.token为关键字,获取相应的Service,然后调用onBind,这里的onBind即是在自定义Service中重写的onBind方法,获取该方法中返回的Binder对象。

然后继续调用ActivityManagerNative.getDefault().publishService来处理;

由前面易知ActivityManagerNative.getDefault()的实际类型为ActivityManagerProxy:


15、ActivityManagerProxy#publishService:

/** @path:  \frameworks\base\core\java\android\app\ActivityManagerNative.java**/class ActivityManagerProxy implements IActivityManager {    public void publishService(IBinder token,                               Intent intent, IBinder service) throws RemoteException {        Parcel data = Parcel.obtain();        Parcel reply = Parcel.obtain();        data.writeInterfaceToken(IActivityManager.descriptor);        data.writeStrongBinder(token);        intent.writeToParcel(data, 0);        data.writeStrongBinder(service);        mRemote.transact(PUBLISH_SERVICE_TRANSACTION, data, reply, 0);        reply.readException();        data.recycle();        reply.recycle();    }}
发送一个 PUBLISH_SERVICE_TRANSACTION类型的IPC请求给AMS;

中间跳转过程省略,AMS处理PUBLISH_SERVICE_TRANSACTION类型请求的方法为:ActivityManagerService.publishService


16、ActivityManagerService#publishService:

public void publishService(IBinder token, Intent intent, IBinder service) {    // Refuse possible leaked file descriptors    if (intent != null && intent.hasFileDescriptors() == true) {        throw new IllegalArgumentException("File descriptors passed in Intent");    }    synchronized(this) {        if (!(token instanceof ServiceRecord)) {            throw new IllegalArgumentException("Invalid service token");        }        mServices.publishServiceLocked((ServiceRecord)token, intent, service);    }}
这里会首先判断传入的参数是否为ServiceRecord,如果不是,则直接报错;

然后交托给ActiveServices的publishServiceLocked去处理;


17、ActiveServices#publishServiceLocked:

/** @path: \frameworks\base\services\core\java\com\android\server\am\ActiveServices.java**/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对象            IntentBindRecord b = r.bindings.get(filter);            if (b != null && !b.received) {                b.binder = service;                b.requested = true;                b.received = true; // 用来表示Services组件是否已经传递给AMS了,如果否则进入此处理函数中                for (int conni=r.connections.size()-1; conni>=0; conni--) {                    // 获取ConnectionRecord                    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是InnerConnection对象,调用其connected函数来进行连接                            c.conn.connected(r.name, service);                        } catch (Exception e) {                        }                    }                }            }            serviceDoneExecutingLocked(r, mDestroyingServices.contains(r), false);        }    } finally {        Binder.restoreCallingIdentity(origId);    }}
可以看到代码中主要的是获取到之前保存的 ConnectionRecord对象,然后调用其conn变量(InnerConnection对象,其实际类型为自定义的ServiceConnection封装成的ServiceDispatcher.ServiceConnection)的connected方法进行连接;

同时可以看到同一个ServiceConnection只会连接一次,因为ConnectionRecord对象的received变量会置为true,下一调用onBind时,并不会继续跳入到绑定逻辑代码中执行connect操作;


18、LoadedApk#ServiceDispatcher#InnerConnection#connected:

/** @path: \frameworks\base\core\java\android\app\LoadedApk.java**/static final class ServiceDispatcher {    private static class InnerConnection extends IServiceConnection.Stub {        final WeakReference<ServiceDispatcher> mDispatcher;        InnerConnection(ServiceDispatcher sd) {            mDispatcher = new WeakReference<ServiceDispatcher>(sd);        }        public void connected(ComponentName name, IBinder service) throws RemoteException {            ServiceDispatcher sd = mDispatcher.get();            if (sd != null) {                sd.connected(name, service);            }        }    }}
最终又会去调用 ServiceDispatcher的connected函数;


19、LoadedApk#ServiceDispatcher#connected:

/** @path: \frameworks\base\core\java\android\app\LoadedApk.java**/static final class ServiceDispatcher {    public void connected(ComponentName name, IBinder service) {        if (mActivityThread != null) {            mActivityThread.post(new RunConnection(name, service, 0));        } else {            doConnected(name, service);        }    }}
由前面知mActivityThread变量即为H,这里将一个RunConnection发送到主线程中去运行;


20、RunConnection:

/** @path: \frameworks\base\core\java\android\app\LoadedApk.java**/static final class ServiceDispatcher {    private final class RunConnection implements Runnable {        RunConnection(ComponentName name, IBinder service, int command) {            mName = name;            mService = service;            mCommand = command;        }        public void run() {            // 根据命令的不同,执行绑定和取消绑定操作            if (mCommand == 0) {                doConnected(mName, mService);            } else if (mCommand == 1) {                doDeath(mName, mService);            }        }        final ComponentName mName;        final IBinder mService;        final int mCommand;    }}
RunConnection是一个Runnable,其具体的执行逻辑在run中,根据命令Command的不同,执行绑定和取消绑定操作;由19步值,command为0,则执行doConnected;


21、ServiceDispatcher#doConnected: 

/** @path: \frameworks\base\core\java\android\app\LoadedApk.java**/static final class ServiceDispatcher {    private final ServiceConnection mConnection;    public void doConnected(ComponentName name, IBinder service) {        .......        // If there is a new service, it is now connected.        if (service != null) {            mConnection.onServiceConnected(name, service);        }    }    public void doDeath(ComponentName name, IBinder service) {        mConnection.onServiceDisconnected(name);    }}
ServiceDispatcher中保存了在代码中自定义的ServiceConnection,这里的绑定工作即是通过调用其onServiceConnected 来完成;


22、自定义的ServiceConnection:

// 定义ServiceConnectionprivate ServiceConnection conn = new ServiceConnection() {    @Override    public void onServiceConnected(ComponentName name, IBinder service) {        // 通过定义的Binder来获取Service实例来供使用        mService = ((MyService.MyBinder) service).getService();        Log.w(MyService.LOG_TAG, "Activity onServiceConnected");    }    @Override    public void onServiceDisconnected(ComponentName name) {        mService = null;        // 当Service被意外销毁时        Log.w(MyService.LOG_TAG, "Activity onServiceDisconnected");    }};
接下来就可以根据获取到的Service实例来直接对Service进行操作;


0 0
原创粉丝点击