Android应用程序绑定服务(bindService)的过程源代码分析(3)
这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:
这里像上面的Step 11一样,调用ActivityThread.queueOrSendMessage函数来发送消息。
- publicfinalclassActivityThread{
- ......
- publicfinalvoidscheduleBindService(IBindertoken,Intentintent,
- booleanrebind){
- BindServiceDatas=newBindServiceData();
- s.token=token;
- s.intent=intent;
- s.rebind=rebind;
- queueOrSendMessage(H.BIND_SERVICE,s);
- }
- ......
- }
Step 18.ActivityThread.queueOrSendMessage
参考上面的Step 11,不过这里的消息类型是H.BIND_SERVICE。
Step 19.H.sendMessage
参考上面的Step 12,不过这里最终在H.handleMessage函数中,要处理的消息类型是H.BIND_SERVICE:
- publicfinalclassActivityThread{
- ......
- privatefinalclassHextendsHandler{
- ......
- publicvoidhandleMessage(Messagemsg){
- ......
- switch(msg.what){
- ......
- caseBIND_SERVICE:
- handleBindService((BindServiceData)msg.obj);
- break;
- ......
- }
- }
- }
- ......
- }
这里调用ActivityThread.handleBindService函数来进一步处理。
Step 20.ActivityThread.handleBindService
这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:
- publicfinalclassActivityThread{
- ......
- privatefinalvoidhandleBindService(BindServiceDatadata){
- Services=mServices.get(data.token);
- if(s!=null){
- try{
- data.intent.setExtrasClassLoader(s.getClassLoader());
- try{
- if(!data.rebind){
- IBinderbinder=s.onBind(data.intent);
- ActivityManagerNative.getDefault().publishService(
- data.token,data.intent,binder);
- }else{
- ......
- }
- ......
- }catch(RemoteExceptionex){
- }
- }catch(Exceptione){
- ......
- }
- }
- }
- ......
- }
在前面的Step 13执行ActivityThread.handleCreateService函数中,已经将这个CounterService实例保存在mServices中,因此,这里首先通过data.token值将它取回来,保存在本地变量s中,接着执行了两个操作,一个操作是调用s.onBind,即CounterService.onBind获得一个Binder对象,另一个操作就是把这个Binder对象传递给ActivityManagerService。
我们先看CounterService.onBind操作,然后再回到ActivityThread.handleBindService函数中来。
Step 21. CounterService.onBind
这个函数定义在Android系统中的广播(Broadcast)机制简要介绍和学习计划中一文中所介绍的应用程序Broadcast的工程目录下的src/shy/luo/broadcast/CounterService.java文件中:
- publicclassCounterServiceextendsServiceimplementsICounterService{
- ......
- privatefinalIBinderbinder=newCounterBinder();
- publicclassCounterBinderextendsBinder{
- publicCounterServicegetService(){
- returnCounterService.this;
- }
- }
- @Override
- publicIBinderonBind(Intentintent){
- returnbinder;
- }
- ......
- }
这里的onBind函数返回一个是CounterBinder类型的Binder对象,它里面实现一个成员函数getService,用于返回CounterService接口。
至此,应用程序绑定服务过程中的第二步CounterService.onBind就完成了。
回到ActivityThread.handleBindService函数中,获得了这个CounterBinder对象后,就调用ActivityManagerProxy.publishService来通知MainActivity,CounterService已经连接好了。
Step 22.ActivityManagerProxy.publishService
这个函数定义在frameworks/base/core/java/android/app/ActivityManagerNative.java文件中:
- classActivityManagerProxyimplementsIActivityManager
- {
- ......
- publicvoidpublishService(IBindertoken,
- Intentintent,IBinderservice)throwsRemoteException{
- Parceldata=Parcel.obtain();
- Parcelreply=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();
- }
- ......
- }
这里通过Binder驱动程序就进入到ActivityManagerService的publishService函数中去了。
Step 23.ActivityManagerService.publishService
这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:
- publicfinalclassActivityManagerServiceextendsActivityManagerNative
- implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{
- ......
- publicvoidpublishService(IBindertoken,Intentintent,IBinderservice){
- ......
- synchronized(this){
- ......
- ServiceRecordr=(ServiceRecord)token;
- ......
- ......
- if(r!=null){
- Intent.FilterComparisonfilter
- =newIntent.FilterComparison(intent);
- IntentBindRecordb=r.bindings.get(filter);
- if(b!=null&&!b.received){
- b.binder=service;
- b.requested=true;
- b.received=true;
- if(r.connections.size()>0){
- Iterator<ArrayList<ConnectionRecord>>it
- =r.connections.values().iterator();
- while(it.hasNext()){
- ArrayList<ConnectionRecord>clist=it.next();
- for(inti=0;i<clist.size();i++){
- ConnectionRecordc=clist.get(i);
- ......
- try{
- c.conn.connected(r.name,service);
- }catch(Exceptione){
- ......
- }
- }
- }
- }
- }
- ......
- }
- }
- }
- ......
- }
这里传进来的参数token是一个ServiceRecord对象,它是在上面的Step 6中创建的,代表CounterServi
- ServiceRecords=res.record;
- ......
- ConnectionRecordc=newConnectionRecord(b,activity,
- connection,flags,clientLabel,clientIntent);
- IBinderbinder=connection.asBinder();
- ArrayList<ConnectionRecord>clist=s.connections.get(binder);
- if(clist==null){
- clist=newArrayList<ConnectionRecord>();
- s.connections.put(binder,clist);
- }
因此,这里可以从r.connections中将这个ConnectionRecord取出来:
- Iterator<ArrayList<ConnectionRecord>>it
- =r.connections.values().iterator();
- while(it.hasNext()){
- ArrayList<ConnectionRecord>clist=it.next();
- for(inti=0;i<clist.size();i++){
- ConnectionRecordc=clist.get(i);
- ......
- try{
- c.conn.connected(r.name,service);
- }catch(Exceptione){
- ......
- }
- }
- }
每一个ConnectionRecord里面都有一个成员变量conn,它的类型是IServiceConnection,是一个Binder对象的远程接口,这个Binder对象又是什么呢?这就是我们在Step
4中创建的LoadedApk.ServiceDispatcher.InnerConnection对象了。因此,这里执行c.conn.connected函数后就会进入到LoadedApk.ServiceDispatcher.InnerConnection.connected函数中去了。
Step 24. InnerConnection.connected
这个函数定义在frameworks/base/core/java/android/app/LoadedApk.java文件中:
- finalclassLoadedApk{
- ......
- staticfinalclassServiceDispatcher{
- ......
- privatestaticclassInnerConnectionextendsIServiceConnection.Stub{
- ......
- publicvoidconnected(ComponentNamename,IBinderservice)throwsRemoteException{
- LoadedApk.ServiceDispatchersd=mDispatcher.get();
- if(sd!=null){
- sd.connected(name,service);
- }
- }
- ......
- }
- ......
- }
- ......
- }
这里它将操作转发给ServiceDispatcher.connected函数。
Step 25.ServiceDispatcher.connected
这个函数定义在frameworks/base/core/java/android/app/LoadedApk.java文件中:
- finalclassLoadedApk{
- ......
- staticfinalclassServiceDispatcher{
- ......
- publicvoidconnected(ComponentNamename,IBinderservice){
- if(mActivityThread!=null){
- mActivityThread.post(newRunConnection(name,service,0));
- }else{
- ......
- }
- }
- ......
- }
- ......
- }
我们在前面Step 4中说到,这里的mActivityThread是一个Handler实例,它是通过ActivityThread.getHandler函数得到的,因此,调用它的post函数后,就会把一个消息放到ActivityThread的消息队列中去了。
Step 26. H.post
由于H类继承于Handler类,因此,这里实际执行的Handler.post函数,这个函数定义在frameworks/base/core/java/android/os/Handler.java文件,这里我们就不看了,有兴趣的读者可以自己研究一下,调用了这个函数之后,这个消息就真正地进入到ActivityThread的消息队列去了,与sendMessage把消息放在消息队列不一样的地方是,post方式发送的消息不是由这个Handler的handleMessage函数来处理的,而是由post的参数Runnable的run函数来处理的。这里传给post的参数是一个RunConnection类型的参数,它继承了Runnable类,因此,最终会调用RunConnection.run函数来处理这个消息。
Step 27.RunConnection.run
这个函数定义在frameworks/base/core/java/android/app/LoadedApk.java文件中:
- finalclassLoadedApk{
- ......
- staticfinalclassServiceDispatcher{
- ......
- privatefinalclassRunConnectionimplementsRunnable{
- ......
- publicvoidrun(){
- if(mCommand==0){
- doConnected(mName,mService);
- }elseif(mCommand==1){
- ......
- }
- }
- ......
- }
- ......
- }
- ......
- }
这里的mCommand值为0,于是就执行ServiceDispatcher.doConnected函数来进一步操作了。
Step 28.ServiceDispatcher.doConnected
这个函数定义在frameworks/base/core/java/android/app/LoadedApk.java文件中:
- finalclassLoadedApk{
- ......
- staticfinalclassServiceDispatcher{
- ......
- publicvoiddoConnected(ComponentNamename,IBinderservice){
- ......
- //Ifthereisanewservice,itisnowconnected.
- if(service!=null){
- mConnection.onServiceConnected(name,service);
- }
- }
- ......
- }
- ......
- }
这里主要就是执行成员变量mConnection的onServiceConnected函数,这里的mConnection变量的类型的ServiceConnection,它是在前面的Step 4中设置好的,这个ServiceConnection实例是MainActivity类内部创建的,在调用bindService函数时保存在LoadedApk.ServiceDispatcher类中,用它来换取一个IServiceConnection对象,传给ActivityManagerService。
Step 29. ServiceConnection.onServiceConnected
这个函数定义在Android系统中的广播(Broadcast)机制简要介绍和学习计划中一文中所介绍的应用程序Broadcast的工程目录下的src/shy/luo/broadcast/MainActivity.java文件中:
- publicclassMainActivityextendsActivityimplementsOnClickListener{
- ......
- privateServiceConnectionserviceConnection=newServiceConnection(){
- publicvoidonServiceConnected(ComponentNameclassName,IBinderservice){
- counterService=((CounterService.CounterBinder)service).getService();
- Log.i(LOG_TAG,"CounterServiceConnected");
- }
- ......
- };
- ......
- }
这里传进来的参数service是一个Binder对象,就是前面在Step 21中从CounterService那里得到的ConterBinder对象,因此,这里可以把它强制转换为CounterBinder引用,然后调用它的getService函数。
至此,应用程序绑定服务过程中的第三步MainActivity.ServiceConnection.onServiceConnection就完成了。
Step 30. CounterBinder.getService
这个函数定义在Android系统中的广播(Broadcast)机制简要介绍和学习计划中一文中所介绍的应用程序Broadcast的工程目录下的src/shy/luo/broadcast/CounterService.java文件中:
- publicclassCounterServiceextendsServiceimplementsICounterService{
- ......
- publicclassCounterBinderextendsBinder{
- publicCounterServicegetService(){
- returnCounterService.this;
- }
- }
- ......
- }
这里就把CounterService接口返回给MainActivity了。
至此,应用程序绑定服务过程中的第四步CounterService.CounterBinder.getService就完成了。
这样,Android应用程序绑定服务(bindService)的过程的源代码分析就完成了,总结一下这个过程:
1. Step 1 - Step 14,MainActivity调用bindService函数通知ActivityManagerService,它要启动CounterService这个服务,ActivityManagerService于是在MainActivity所在的进程内部把CounterService启动起来,并且调用它的onCreate函数;
2. Step 15 - Step 21,ActivityManagerService把CounterService启动起来后,继续调用CounterService的onBind函数,要求CounterService返回一个Binder对象给它;
3. Step 22 - Step 29,ActivityManagerService从CounterService处得到这个Binder对象后,就把它传给MainActivity,即把这个Binder对象作为参数传递给MainActivity内部定义的ServiceConnection对象的onServiceConnected函数;
4. Step 30,MainActivity内部定义的ServiceConnection对象的onServiceConnected函数在得到这个Binder对象后,就通过它的getService成同函数获得CounterService接口。
更多相关文章
- C语言函数以及函数的使用
- Android 高德地图在清除Marker的时候会把自定义的定位蓝点也清除
- Android定义的路径全局变量
- 自定义View
- android Activity之间传递对象
- Android自定义Button背景色,弧度
- FregClient进程,创建一个BpFregService类型的代理对象