Step 17.ApplicationThread.scheduleBindService
这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:
        
  1. publicfinalclassActivityThread{
  2. ......
  3. publicfinalvoidscheduleBindService(IBindertoken,Intentintent,
  4. booleanrebind){
  5. BindServiceDatas=newBindServiceData();
  6. s.token=token;
  7. s.intent=intent;
  8. s.rebind=rebind;
  9. queueOrSendMessage(H.BIND_SERVICE,s);
  10. }
  11. ......
  12. }
这里像上面的Step 11一样,调用ActivityThread.queueOrSendMessage函数来发送消息。
Step 18.ActivityThread.queueOrSendMessage

参考上面的Step 11,不过这里的消息类型是H.BIND_SERVICE。

Step 19.H.sendMessage

参考上面的Step 12,不过这里最终在H.handleMessage函数中,要处理的消息类型是H.BIND_SERVICE:

            
  1. publicfinalclassActivityThread{
  2. ......
  3. privatefinalclassHextendsHandler{
  4. ......
  5. publicvoidhandleMessage(Messagemsg){
  6. ......
  7. switch(msg.what){
  8. ......
  9. caseBIND_SERVICE:
  10. handleBindService((BindServiceData)msg.obj);
  11. break;
  12. ......
  13. }
  14. }
  15. }
  16. ......
  17. }

这里调用ActivityThread.handleBindService函数来进一步处理。

Step 20.ActivityThread.handleBindService

这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:

        
  1. publicfinalclassActivityThread{
  2. ......
  3. privatefinalvoidhandleBindService(BindServiceDatadata){
  4. Services=mServices.get(data.token);
  5. if(s!=null){
  6. try{
  7. data.intent.setExtrasClassLoader(s.getClassLoader());
  8. try{
  9. if(!data.rebind){
  10. IBinderbinder=s.onBind(data.intent);
  11. ActivityManagerNative.getDefault().publishService(
  12. data.token,data.intent,binder);
  13. }else{
  14. ......
  15. }
  16. ......
  17. }catch(RemoteExceptionex){
  18. }
  19. }catch(Exceptione){
  20. ......
  21. }
  22. }
  23. }
  24. ......
  25. }

在前面的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文件中:

        
  1. publicclassCounterServiceextendsServiceimplementsICounterService{
  2. ......
  3. privatefinalIBinderbinder=newCounterBinder();
  4. publicclassCounterBinderextendsBinder{
  5. publicCounterServicegetService(){
  6. returnCounterService.this;
  7. }
  8. }
  9. @Override
  10. publicIBinderonBind(Intentintent){
  11. returnbinder;
  12. }
  13. ......
  14. }

这里的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文件中:

        
  1. classActivityManagerProxyimplementsIActivityManager
  2. {
  3. ......
  4. publicvoidpublishService(IBindertoken,
  5. Intentintent,IBinderservice)throwsRemoteException{
  6. Parceldata=Parcel.obtain();
  7. Parcelreply=Parcel.obtain();
  8. data.writeInterfaceToken(IActivityManager.descriptor);
  9. data.writeStrongBinder(token);
  10. intent.writeToParcel(data,0);
  11. data.writeStrongBinder(service);
  12. mRemote.transact(PUBLISH_SERVICE_TRANSACTION,data,reply,0);
  13. reply.readException();
  14. data.recycle();
  15. reply.recycle();
  16. }
  17. ......
  18. }

这里通过Binder驱动程序就进入到ActivityManagerService的publishService函数中去了。

Step 23.ActivityManagerService.publishService

这个函数定义在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中:

        
  1. publicfinalclassActivityManagerServiceextendsActivityManagerNative
  2. implementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{
  3. ......
  4. publicvoidpublishService(IBindertoken,Intentintent,IBinderservice){
  5. ......
  6. synchronized(this){
  7. ......
  8. ServiceRecordr=(ServiceRecord)token;
  9. ......
  10. ......
  11. if(r!=null){
  12. Intent.FilterComparisonfilter
  13. =newIntent.FilterComparison(intent);
  14. IntentBindRecordb=r.bindings.get(filter);
  15. if(b!=null&&!b.received){
  16. b.binder=service;
  17. b.requested=true;
  18. b.received=true;
  19. if(r.connections.size()>0){
  20. Iterator<ArrayList<ConnectionRecord>>it
  21. =r.connections.values().iterator();
  22. while(it.hasNext()){
  23. ArrayList<ConnectionRecord>clist=it.next();
  24. for(inti=0;i<clist.size();i++){
  25. ConnectionRecordc=clist.get(i);
  26. ......
  27. try{
  28. c.conn.connected(r.name,service);
  29. }catch(Exceptione){
  30. ......
  31. }
  32. }
  33. }
  34. }
  35. }
  36. ......
  37. }
  38. }
  39. }
  40. ......
  41. }

这里传进来的参数token是一个ServiceRecord对象,它是在上面的Step 6中创建的,代表CounterServi

        
  1. ServiceRecords=res.record;
  2. ......
  3. ConnectionRecordc=newConnectionRecord(b,activity,
  4. connection,flags,clientLabel,clientIntent);
  5. IBinderbinder=connection.asBinder();
  6. ArrayList<ConnectionRecord>clist=s.connections.get(binder);
  7. if(clist==null){
  8. clist=newArrayList<ConnectionRecord>();
  9. s.connections.put(binder,clist);
  10. }

因此,这里可以从r.connections中将这个ConnectionRecord取出来:

        
  1. Iterator<ArrayList<ConnectionRecord>>it
  2. =r.connections.values().iterator();
  3. while(it.hasNext()){
  4. ArrayList<ConnectionRecord>clist=it.next();
  5. for(inti=0;i<clist.size();i++){
  6. ConnectionRecordc=clist.get(i);
  7. ......
  8. try{
  9. c.conn.connected(r.name,service);
  10. }catch(Exceptione){
  11. ......
  12. }
  13. }
  14. }

每一个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文件中:

        
  1. finalclassLoadedApk{
  2. ......
  3. staticfinalclassServiceDispatcher{
  4. ......
  5. privatestaticclassInnerConnectionextendsIServiceConnection.Stub{
  6. ......
  7. publicvoidconnected(ComponentNamename,IBinderservice)throwsRemoteException{
  8. LoadedApk.ServiceDispatchersd=mDispatcher.get();
  9. if(sd!=null){
  10. sd.connected(name,service);
  11. }
  12. }
  13. ......
  14. }
  15. ......
  16. }
  17. ......
  18. }

这里它将操作转发给ServiceDispatcher.connected函数。

Step 25.ServiceDispatcher.connected

这个函数定义在frameworks/base/core/java/android/app/LoadedApk.java文件中:

        
  1. finalclassLoadedApk{
  2. ......
  3. staticfinalclassServiceDispatcher{
  4. ......
  5. publicvoidconnected(ComponentNamename,IBinderservice){
  6. if(mActivityThread!=null){
  7. mActivityThread.post(newRunConnection(name,service,0));
  8. }else{
  9. ......
  10. }
  11. }
  12. ......
  13. }
  14. ......
  15. }

我们在前面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文件中:

        
  1. finalclassLoadedApk{
  2. ......
  3. staticfinalclassServiceDispatcher{
  4. ......
  5. privatefinalclassRunConnectionimplementsRunnable{
  6. ......
  7. publicvoidrun(){
  8. if(mCommand==0){
  9. doConnected(mName,mService);
  10. }elseif(mCommand==1){
  11. ......
  12. }
  13. }
  14. ......
  15. }
  16. ......
  17. }
  18. ......
  19. }

这里的mCommand值为0,于是就执行ServiceDispatcher.doConnected函数来进一步操作了。

Step 28.ServiceDispatcher.doConnected
这个函数定义在frameworks/base/core/java/android/app/LoadedApk.java文件中:

        
  1. finalclassLoadedApk{
  2. ......
  3. staticfinalclassServiceDispatcher{
  4. ......
  5. publicvoiddoConnected(ComponentNamename,IBinderservice){
  6. ......
  7. //Ifthereisanewservice,itisnowconnected.
  8. if(service!=null){
  9. mConnection.onServiceConnected(name,service);
  10. }
  11. }
  12. ......
  13. }
  14. ......
  15. }

这里主要就是执行成员变量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文件中:

        
  1. publicclassMainActivityextendsActivityimplementsOnClickListener{
  2. ......
  3. privateServiceConnectionserviceConnection=newServiceConnection(){
  4. publicvoidonServiceConnected(ComponentNameclassName,IBinderservice){
  5. counterService=((CounterService.CounterBinder)service).getService();
  6. Log.i(LOG_TAG,"CounterServiceConnected");
  7. }
  8. ......
  9. };
  10. ......
  11. }

这里传进来的参数service是一个Binder对象,就是前面在Step 21中从CounterService那里得到的ConterBinder对象,因此,这里可以把它强制转换为CounterBinder引用,然后调用它的getService函数。

至此,应用程序绑定服务过程中的第三步MainActivity.ServiceConnection.onServiceConnection就完成了。

Step 30. CounterBinder.getService

这个函数定义在Android系统中的广播(Broadcast)机制简要介绍和学习计划中一文中所介绍的应用程序Broadcast的工程目录下的src/shy/luo/broadcast/CounterService.java文件中:

        
  1. publicclassCounterServiceextendsServiceimplementsICounterService{
  2. ......
  3. publicclassCounterBinderextendsBinder{
  4. publicCounterServicegetService(){
  5. returnCounterService.this;
  6. }
  7. }
  8. ......
  9. }

这里就把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接口。

更多相关文章

  1. C语言函数以及函数的使用
  2. Android 高德地图在清除Marker的时候会把自定义的定位蓝点也清除
  3. Android定义的路径全局变量
  4. 自定义View
  5. android Activity之间传递对象
  6. Android自定义Button背景色,弧度
  7. FregClient进程,创建一个BpFregService类型的代理对象

随机推荐

  1. 如何使用MySql和PHP存储/处理多个表的数
  2. 使用cmake安装mysql5.5.13
  3. Linux测试环境搭建apache+mysql+php
  4. 如何使用本地phmyadmin客户端访问远程服
  5. Failed while installing Dynamic Web Mo
  6. MySQLDriverCS Exception: MySQLDriverCS
  7. Mysql字符集和校验规则
  8. PHP读取Excel文件的内容并写入Mysql数据
  9. 有多少MySQL行太多?
  10. PHP新的连接MySQL方法mysqli