且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Android应用程序绑定服务(bindService)的过程源代码分析(2)

更新时间:2022-07-05 15:35:32

  Step 7. ActivityManagerService.bringUpServiceLocked

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


  1. public final class ActivityManagerService extends ActivityManagerNative   
  2.         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {   
  3.     ......   
  4.    
  5.     private final boolean bringUpServiceLocked(ServiceRecord r,   
  6.             int intentFlags, boolean whileRestarting) {   
  7.         ......   
  8.    
  9.         final String appName = r.processName;   
  10.         ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);   
  11.    
  12.         if (app != null && app.thread != null) {   
  13.             try {   
  14.                 realStartServiceLocked(r, app);   
  15.                 return true;   
  16.             } catch (RemoteException e) {   
  17.                 ......   
  18.             }   
  19.         }   
  20.    
  21.         // Not running -- get it started, and enqueue this service record   
  22.         // to be executed when the app comes up.   
  23.         if (startProcessLocked(appName, r.appInfo, true, intentFlags,   
  24.             "service", r.name, false) == null) {   
  25.                 ......   
  26.         }   
  27.    
  28.         ......   
  29.     }   
  30.    
  31.     ......   
  32. }   

 

        回忆在Android系统中的广播(Broadcast)机制简要介绍和学习计划中一文中,我们没有在程序的AndroidManifest.xml配置文件中设置CounterService的process属性值,因此,它默认就为application标签的process属性值,而application标签的process属性值也没有设置,于是,它们就默认为应用程序的包名了,即这里的appName的值为"shy.luo.broadcast"。接下来根据appName和应用程序的uid值获得一个ProcessRecord记录,由于之前在启动MainActivity的时候,已经根据这个appName和uid值创建了一个ProcessReocrd对象(具体可以参考Android应用程序启动过程源代码分析一文),因此,这里取回来的app和app.thread均不为null,于是,就执行realStartServiceLocked函数来执行下一步操作了。

        如果这里得到的ProcessRecord变量app为null,又是什么情况呢?在这种情况下,就会执行后面的startProcessLocked函数来创建一个新的进程,然后在这个新的进程中启动这个Service了,具体可以参考前面一篇文章Android系统在新进程中启动自定义服务过程(startService)的原理分析

        Step 8. ActivityManagerService.realStartServiceLocked

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


  1. public final class ActivityManagerService extends ActivityManagerNative   
  2.         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {   
  3.     ......   
  4.    
  5.     private final void realStartServiceLocked(ServiceRecord r,   
  6.             ProcessRecord app) throws RemoteException {   
  7.         ......   
  8.         r.app = app;   
  9.         ......   
  10.    
  11.         app.services.add(r);   
  12.         ......   
  13.    
  14.         try {   
  15.             ......   
  16.             app.thread.scheduleCreateService(r, r.serviceInfo);   
  17.             ......   
  18.         } finally {   
  19.             ......   
  20.         }   
  21.    
  22.         requestServiceBindingsLocked(r);   
  23.    
  24.         ......   
  25.     }   
  26.    
  27.     ......   
  28. }   

 

        这个函数执行了两个操作,一个是操作是调用app.thread.scheduleCreateService函数来在应用程序进程内部启动CounterService,这个操作会导致CounterService的onCreate函数被调用;另一个操作是调用requestServiceBindingsLocked函数来向CounterService要一个Binder对象,这个操作会导致CounterService的onBind函数被调用。

        这里,我们先沿着app.thread.scheduleCreateService这个路径分析下去,然后再回过头来分析requestServiceBindingsLocked的调用过程。这里的app.thread是一个Binder对象的远程接口,类型为ApplicationThreadProxy。每一个Android应用程序进程里面都有一个ActivtyThread对象和一个ApplicationThread对象,其中是ApplicationThread对象是ActivityThread对象的一个成员变量,是ActivityThread与ActivityManagerService之间用来执行进程间通信的,具体可以参考Android应用程序启动过程源代码分析一文。

        Step 9. ApplicationThreadProxy.scheduleCreateService

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


  1. class ApplicationThreadProxy implements IApplicationThread {   
  2.     ......   
  3.    
  4.     public final void scheduleCreateService(IBinder token, ServiceInfo info)   
  5.             throws RemoteException {   
  6.         Parcel data = Parcel.obtain();   
  7.         data.writeInterfaceToken(IApplicationThread.descriptor);   
  8.         data.writeStrongBinder(token);   
  9.         info.writeToParcel(data, 0);   
  10.         mRemote.transact(SCHEDULE_CREATE_SERVICE_TRANSACTION, data, null,   
  11.             IBinder.FLAG_ONEWAY);   
  12.         data.recycle();   
  13.     }   
  14.    
  15.     ......   
  16. }   

 

         这里通过Binder驱动程序就进入到ApplicationThread的scheduleCreateService函数去了。

 

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


  1. public final class ActivityThread {   
  2.     ......   
  3.    
  4.     private final class ApplicationThread extends ApplicationThreadNative {   
  5.         ......   
  6.    
  7.         public final void scheduleCreateService(IBinder token,   
  8.             ServiceInfo info) {   
  9.             CreateServiceData s = new CreateServiceData();   
  10.             s.token = token;   
  11.             s.info = info;   
  12.    
  13.             queueOrSendMessage(H.CREATE_SERVICE, s);   
  14.         }   
  15.    
  16.         ......   
  17.     }   
  18.    
  19.     ......   
  20. }   

 

         这里它执行的操作就是调用ActivityThread的queueOrSendMessage函数把一个H.CREATE_SERVICE类型的消息放到ActivityThread的消息队列中去。

 

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


  1. public final class ActivityThread {   
  2.     ......   
  3.    
  4.     // if the thread hasn't started yet, we don't have the handler, so just   
  5.     // save the messages until we're ready.   
  6.     private final void queueOrSendMessage(int what, Object obj) {   
  7.         queueOrSendMessage(what, obj, 00);   
  8.     }   
  9.    
  10.     private final void queueOrSendMessage(int what, Object obj, int arg1) {   
  11.         queueOrSendMessage(what, obj, arg1, 0);   
  12.     }   
  13.    
  14.     private final void queueOrSendMessage(int what, Object obj, int arg1, int arg2) {   
  15.         synchronized (this) {   
  16.             ......   
  17.             Message msg = Message.obtain();   
  18.             msg.what = what;   
  19.             msg.obj = obj;   
  20.             msg.arg1 = arg1;   
  21.             msg.arg2 = arg2;   
  22.             mH.sendMessage(msg);   
  23.         }   
  24.     }   
  25.    
  26.     ......   
  27. }   

 

       这个消息最终是通过mH.sendMessage发送出去的,这里的mH是一个在ActivityThread内部定义的一个类,继承于Hanlder类,用于处理消息的。

 

        Step 12. H.sendMessage

        由于H类继承于Handler类,因此,这里实际执行的Handler.sendMessage函数,这个函数定义在frameworks/base/core/java/android/os/Handler.java文件,这里我们就不看了,有兴趣的读者可以自己研究一下,调用了这个函数之后,这个消息就真正地进入到ActivityThread的消息队列去了,最终这个消息由H.handleMessage函数来处理,这个函数定义在frameworks/base/core/java/android/app/ActivityThread.java文件中:


  1. public final class ActivityThread {   
  2.     ......   
  3.    
  4.     private final class H extends Handler {   
  5.         ......   
  6.    
  7.         public void handleMessage(Message msg) {   
  8.             ......   
  9.             switch (msg.what) {   
  10.             ......   
  11.             case CREATE_SERVICE:   
  12.                 handleCreateService((CreateServiceData)msg.obj);   
  13.                 break;   
  14.             ......   
  15.             }   
  16.         }   
  17.     }   
  18.    
  19.     ......   
  20. }   

 

     这个消息最终由ActivityThread的handleCreateService函数来处理。

 

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


  1. public final class ActivityThread {   
  2.     ......   
  3.    
  4.     private final void handleCreateService(CreateServiceData data) {   
  5.         ......   
  6.    
  7.         LoadedApk packageInfo = getPackageInfoNoCheck(   
  8.         data.info.applicationInfo);   
  9.         Service service = null;   
  10.         try {   
  11.             java.lang.ClassLoader cl = packageInfo.getClassLoader();   
  12.             service = (Service) cl.loadClass(data.info.name).newInstance();   
  13.         } catch (Exception e) {   
  14.             ......   
  15.         }   
  16.    
  17.         try {   
  18.             ......   
  19.    
  20.             ContextImpl context = new ContextImpl();   
  21.             context.init(packageInfo, nullthis);   
  22.    
  23.             Application app = packageInfo.makeApplication(false, mInstrumentation);   
  24.             context.setOuterContext(service);   
  25.             service.attach(context, this, data.info.name, data.token, app,   
  26.                 ActivityManagerNative.getDefault());   
  27.    
  28.             service.onCreate();   
  29.             mServices.put(data.token, service);   
  30.             ......   
  31.         } catch (Exception e) {   
  32.             ......   
  33.         }   
  34.     }   
  35.    
  36.     ......   
  37. }   

 

 

         这个函数的工作就是把CounterService类加载到内存中来,然后调用它的onCreate函数。

         Step 14. CounterService.onCreate

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


  1. public class CounterService extends Service implements ICounterService {   
  2.     ......   
  3.    
  4.     @Override     
  5.     public void onCreate() {     
  6.         super.onCreate();     
  7.    
  8.         Log.i(LOG_TAG, "Counter Service Created.");     
  9.     }    
  10.    
  11.     ......   
  12. }   

   这样,CounterService就启动起来了。

 

        至此,应用程序绑定服务过程中的第一步MainActivity.bindService->CounterService.onCreate就完成了。

        这一步完成之后,我们还要回到Step  8中去,执行下一个操作,即调用ActivityManagerService.requestServiceBindingsLocked函数,这个调用是用来执行CounterService的onBind函数的。        Step 15. ActivityManagerService.requestServiceBindingsLocked

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


  1. public final class ActivityManagerService extends ActivityManagerNative   
  2.         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {   
  3.     ......   
  4.    
  5.     private final void requestServiceBindingsLocked(ServiceRecord r) {   
  6.         Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();   
  7.         while (bindings.hasNext()) {   
  8.             IntentBindRecord i = bindings.next();   
  9.             if (!requestServiceBindingLocked(r, i, false)) {   
  10.                 break;   
  11.             }   
  12.         }   
  13.     }   
  14.    
  15.     private final boolean requestServiceBindingLocked(ServiceRecord r,   
  16.             IntentBindRecord i, boolean rebind) {   
  17.         ......   
  18.         if ((!i.requested || rebind) && i.apps.size() > 0) {   
  19.           try {   
  20.               ......   
  21.               r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);   
  22.               ......   
  23.           } catch (RemoteException e) {   
  24.               ......   
  25.           }   
  26.         }   
  27.         return true;   
  28.     }   
  29.    
  30.     ......   
  31. }   

       这里的参数r就是我们在前面的Step 6中创建的ServiceRecord了,它代表刚才已经启动了的CounterService。函数requestServiceBindingsLocked调用了requestServiceBindingLocked函数来处理绑定服务的操作,而函数requestServiceBindingLocked又调用了app.thread.scheduleBindService函数执行操作,前面我们已经介绍过app.thread,它是一个Binder对象的远程接口,类型是ApplicationThreadProxy。       Step 16. ApplicationThreadProxy.scheduleBindService

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


  1. class ApplicationThreadProxy implements IApplicationThread {   
  2.     ......   
  3.        
  4.     public final void scheduleBindService(IBinder token, Intent intent, boolean rebind)   
  5.             throws RemoteException {   
  6.         Parcel data = Parcel.obtain();   
  7.         data.writeInterfaceToken(IApplicationThread.descriptor);   
  8.         data.writeStrongBinder(token);   
  9.         intent.writeToParcel(data, 0);   
  10.         data.writeInt(rebind ? 1 : 0);   
  11.         mRemote.transact(SCHEDULE_BIND_SERVICE_TRANSACTION, data, null,   
  12.             IBinder.FLAG_ONEWAY);   
  13.         data.recycle();   
  14.     }   
  15.    
  16.     ......   
  17. }   

         这里通过Binder驱动程序就进入到ApplicationThread的scheduleBindService函数去了。






本文转自 Luoshengyang 51CTO博客,原文链接:http://blog.51cto.com/shyluo/966420,如需转载请自行联系原作者