zoukankan      html  css  js  c++  java
  • Android系统在新进程中启动自定义服务过程(startService)的原理分析

     

            在编写Android应用程序时,我们一般将一些计算型的逻辑放在一个独立的进程来处理,这样主进程仍然可以流畅地响应界面事件,提高用户体验。 Android系统为我们提供了一个Service类,我们可以实现一个以Service为基类的服务子类,在里面实现自己的计算型逻辑,然后在主进程通 过startService函数来启动这个服务。在本文中,将详细分析主进程是如何通过startService函数来在新进程中启动自定义服务的。

            在主进程调用startService函数时,会通过Binder进程间通信机制来通知ActivitManagerService来创建新进程,并且 启动指定的服务。在Android系统中,Binder进程间通信机制使用非常广泛,因此,希望读者在继续阅读下面的内容之前,对Android系统和 Binder进程间通信机制有一定的了解,具体可以参考前面Android进程间通信(IPC)机制Binder简要介绍和学习计划一文。

            关于startService的具体用法,可以参考前面Android系统匿名共享内存Ashmem(Anonymous Shared Memory)简要介绍和学习计划一文中用到的实例,它是Activity类的一个成员函数:

    1. package shy.luo.ashmem;  
    2.   
    3. ......  
    4.   
    5. public class Client extends Activity implements OnClickListener {  
    6.     ......  
    7.     IMemoryService memoryService = null;  
    8.     ......  
    9.   
    10.     @Override  
    11.     public void onCreate(Bundle savedInstanceState) {  
    12.         ......  
    13.   
    14.         IMemoryService ms = getMemoryService();  
    15.         if(ms == null) {          
    16.             startService(new Intent("shy.luo.ashmem.server"));  
    17.         } else {  
    18.             Log.i(LOG_TAG, "Memory Service has started.");  
    19.         }  
    20.   
    21.         ......  
    22.   
    23.         Log.i(LOG_TAG, "Client Activity Created.");  
    24.     }  
    25.   
    26.     ......  
    27. }  

            这里的“shy.luo.ashmem.server”是在程序配置文件AndroidManifest.xml配置的Service的名字,用来告诉Android系统它所要启动的服务的名字:

    1. <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
    2.     package="shy.luo.ashmem"  
    3.     android:sharedUserId="android.uid.system"  
    4.     android:versionCode="1"  
    5.     android:versionName="1.0">  
    6.         <application android:icon="@drawable/icon" android:label="@string/app_name">  
    7.             ......  
    8.             <service   
    9.                 android:enabled="true"   
    10.                 android:name=".Server"  
    11.                 android:process=".Server" >  
    12.                     <intent-filter>  
    13.                         <action android:name="shy.luo.ashmem.server"/>  
    14.                         <category android:name="android.intent.category.DEFAULT"/>  
    15.                     </intent-filter>  
    16.             </service>  
    17.         </application>  
    18. </manifest>   

             这里,名字“shy.luo.ashmem.server”对应的服务类为shy.luo.ashmem.Server,下面语句:

    1. startService(new Intent("shy.luo.ashmem.server"));  

             就表示要在一个新的进程中启动shy.luo.ashmem.Server这个服务类,它必须继承于Android平台提供的Service类:

    1. package shy.luo.ashmem;  
    2.   
    3. ......  
    4.   
    5. public class Server extends Service {  
    6.       
    7.     ......  
    8.   
    9.     @Override  
    10.     public IBinder onBind(Intent intent) {  
    11.             return null;  
    12.     }  
    13.   
    14.     @Override  
    15.     public void onCreate() {  
    16.         ......  
    17.   
    18.     }  
    19.   
    20.     ......  
    21. }  

            下面,我们来看看Activity类中的startService成员函数是如何实现的。

            先来看看Activity的类图:


            从图中可以看出,Activity继承了ContextWrapper类,而在ContextWrapper类中,实现了startService函 数。在ContextWrapper类中,有一个成员变量mBase,它是一个ContextImpl实例,而ContextImpl类和 ContextWrapper类一样继承于Context类,ContextWrapper类的startService函数最终过调用 ContextImpl类的startService函数来实现。这种类设计方法在设计模式里面,就称之为装饰模式(Decorator),或者包装模式 (Wrapper)。

            在ContextImpl类的startService类,最终又调用了ActivityManagerProxy类的startService来实现启动服务的操作,看到这里的Proxy关键字,回忆一下前面Android系统进程间通信Binder机制在应用程序框架层的Java接口源代码分析这篇文章,就会知道ActivityManagerProxy是一个Binder对象的远程接口了,而这个Binder对象就是我们前面所说的ActivityManagerService了。

            这个ActivityManagerService类实现在frameworks/base/services/java/com/android /server/am/ActivityManagerService.java文件中,它是Binder进程间通信机制中的Server角色,它是随机 启动的。随机启动的Server是在frameworks/base/services/java/com/android/server /SystemServer.java文件里面进行启动的,我们来看一下ActivityManagerService启动相关的代码:

    1. class ServerThread extends Thread {  
    2.       
    3.     ......  
    4.   
    5.     @Override  
    6.     public void run() {  
    7.   
    8.         ......  
    9.   
    10.         // Critical services...  
    11.         try {  
    12.   
    13.             ......  
    14.   
    15.             context = ActivityManagerService.main(factoryTest);  
    16.   
    17.             ......  
    18.   
    19.             ActivityManagerService.setSystemProcess();  
    20.   
    21.             ......  
    22.           
    23.         } catch (RuntimeException e) {  
    24.             Slog.e("System", "Failure starting core service", e);  
    25.         }  
    26.   
    27.         ......  
    28.       
    29.     }  
    30.   
    31.     ......  
    32.   
    33. }  

              首先是调用ActivityManagerService.main函数来创建一个ActivityManagerService实例,然后通过调用 ActivityManagerService.setSystemProcess函数把这个Binder实例添加Binder进程间通信机制的守护进程 ServiceManager中去:

    1. public final class ActivityManagerService extends ActivityManagerNative  
    2.         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {  
    3.   
    4.     ......  
    5.   
    6.     static ActivityManagerService mSelf;  
    7.   
    8.     ......  
    9.   
    10.     public static void setSystemProcess() {  
    11.         try {  
    12.             ActivityManagerService m = mSelf;  
    13.   
    14.             ServiceManager.addService("activity", m);  
    15.               
    16.             ......  
    17.   
    18.         } catch (PackageManager.NameNotFoundException e) {  
    19.             ......  
    20.         }  
    21.     }  
    22.   
    23.     ......  
    24.   
    25.     public static final Context main(int factoryTest) {  
    26.           
    27.         ......  
    28.   
    29.         ActivityManagerService m = thr.mService;  
    30.         mSelf = m;  
    31.   
    32.         ......  
    33.   
    34.     }  
    35. }  

             这样,ActivityManagerService就启动起来了。

             回到ActivityManagerProxy类的startService函数中,它定义在frameworks/base/core/java/android/app/ActivityManagerNative.java文件中:

    1. class ActivityManagerProxy implements IActivityManager  
    2. {  
    3.     ......  
    4.   
    5.     public ComponentName startService(IApplicationThread caller, Intent service,  
    6.         String resolvedType) throws RemoteException  
    7.     {  
    8.         Parcel data = Parcel.obtain();  
    9.         Parcel reply = Parcel.obtain();  
    10.         data.writeInterfaceToken(IActivityManager.descriptor);  
    11.         data.writeStrongBinder(caller != null ? caller.asBinder() : null);  
    12.         service.writeToParcel(data, 0);  
    13.         data.writeString(resolvedType);  
    14.         mRemote.transact(START_SERVICE_TRANSACTION, data, reply, 0);  
    15.         reply.readException();  
    16.         ComponentName res = ComponentName.readFromParcel(reply);  
    17.         data.recycle();  
    18.         reply.recycle();  
    19.         return res;  
    20.     }  
    21.   
    22.     ......  
    23. }  

             参数service是一个Intent实例,它里面指定了要启动的服务的名称,就是前面我们所说的“shy.luo.ashmem.server”了。

             参数caller是一个IApplicationThread实例,它是一个在主进程创建的一个Binder对象。在Android应用程序中,每一个进 程都用一个ActivityThread实例来表示,而在ActivityThread类中,有一个成员变量mAppThread,它是一个 ApplicationThread实例,实现了IApplicationThread接口,它的作用是用来辅助ActivityThread类来执行一 些操作,这个我们在后面会看到它是如何用来启动服务的。

            参数resolvedType是一个字符串,它表示service这个Intent的MIME类型,它是在解析Intent时用到的。在这个例子中,我们没有指定这个Intent 的MIME类型,因此,这个参数为null。

            ActivityManagerProxy类的startService函数把这三个参数写入到data本地变量去,接着通过 mRemote.transact函数进入到Binder驱动程序,然后Binder驱动程序唤醒正在等待Client请求的 ActivityManagerService进程,最后进入到ActivityManagerService的startService函数中。

            ActivityManagerService的startService函数的处理流程如下图所示:

     点击查看大图

              在这个序列图中,一共有20个步骤,下面说明每一步。

             Step 1. ActivityManagerService.startService

             这个函数定义在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.   
    6.     public ComponentName startService(IApplicationThread caller, Intent service,  
    7.             String resolvedType) {        
    8.           // Refuse possible leaked file descriptors  
    9.           if (service != null && service.hasFileDescriptors() == true) {  
    10.               throw new IllegalArgumentException("File descriptors passed in Intent");  
    11.           }  
    12.   
    13.           synchronized(this) {  
    14.               final int callingPid = Binder.getCallingPid();  
    15.               final int callingUid = Binder.getCallingUid();  
    16.               final long origId = Binder.clearCallingIdentity();  
    17.               ComponentName res = startServiceLocked(caller, service,  
    18.                   resolvedType, callingPid, callingUid);  
    19.               Binder.restoreCallingIdentity(origId);  
    20.               return res;  
    21.           }  
    22.     }  
    23.   
    24.     ......  
    25.   
    26. }  

             这里的参数caller、service和resolvedType分别对应ActivityManagerProxy.startService传进来的三个参数。

             Step 2. ActivityManagerService.startServiceLocked
             这个函数同样定义在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.   
    6.     ComponentName startServiceLocked(IApplicationThread caller,  
    7.             Intent service, String resolvedType,  
    8.             int callingPid, int callingUid) {  
    9.         synchronized(this) {  
    10.             ......  
    11.   
    12.             ServiceLookupResult res =  
    13.                 retrieveServiceLocked(service, resolvedType,  
    14.                 callingPid, callingUid);  
    15.               
    16.             ......  
    17.               
    18.             ServiceRecord r = res.record;  
    19.               
    20.             ......  
    21.   
    22.             if (!bringUpServiceLocked(r, service.getFlags(), false)) {  
    23.                 return new ComponentName("!", "Service process is bad");  
    24.             }  
    25.             return r.name;  
    26.         }  
    27.     }  
    28.   
    29.     ......  
    30.   
    31. }  

            函数首先通过retrieveServiceLocked来解析service这个Intent,就是解析前面我们在 AndroidManifest.xml定义的Service标签的intent-filter相关内容,然后将解析结果放在res.record中,然 后继续调用bringUpServiceLocked进一步处理。

            Step 3. 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.   
    6.     private final boolean bringUpServiceLocked(ServiceRecord r,  
    7.                     int intentFlags, boolean whileRestarting) {  
    8.   
    9.         ......  
    10.   
    11.         final String appName = r.processName;  
    12.   
    13.         ......  
    14.   
    15.         // Not running -- get it started, and enqueue this service record  
    16.         // to be executed when the app comes up.  
    17.         if (startProcessLocked(appName, r.appInfo, true, intentFlags,  
    18.                     "service", r.name, false) == null) {  
    19.   
    20.             ......  
    21.   
    22.             return false;  
    23.         }  
    24.   
    25.         if (!mPendingServices.contains(r)) {  
    26.             mPendingServices.add(r);  
    27.         }  
    28.   
    29.         return true;  
    30.   
    31.     }  
    32.   
    33.     ......  
    34.   
    35. }  

            这里的appName便是我们前面在AndroidManifest.xml文件定义service标签时指定的android:process属性值了,即“.Server”。

            接着调用startProcessLocked函数来创建一个新的进程,以便加载自定义的Service类。最后将这个ServiceRecord保存在成员变量mPendingServices列表中,后面会用到。

            Step 4. ActivityManagerService.startProcessLocked

            这个函数同样定义在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.   
    6.     private final void startProcessLocked(ProcessRecord app,  
    7.                 String hostingType, String hostingNameStr) {  
    8.   
    9.         ......  
    10.   
    11.         try {  
    12.   
    13.             ......  
    14.   
    15.             int pid = Process.start("android.app.ActivityThread",  
    16.                             mSimpleProcessManagement ? app.processName : null, uid, uid,  
    17.                             gids, debugFlags, null);  
    18.   
    19.             ......  
    20.   
    21.             if (pid == 0 || pid == MY_PID) {  
    22.                   
    23.                 ......  
    24.   
    25.             } else if (pid > 0) {  
    26.                 app.pid = pid;  
    27.                 app.removed = false;  
    28.                 synchronized (mPidsSelfLocked) {  
    29.                     this.mPidsSelfLocked.put(pid, app);  
    30.                     ......  
    31.                 }  
    32.             } else {  
    33.                   
    34.                 ......  
    35.             }  
    36.   
    37.         } catch (RuntimeException e) {  
    38.   
    39.             ......  
    40.   
    41.         }  
    42.   
    43.     }  
    44.   
    45.     ......  
    46.   
    47. }  

             这里调用Process.start函数创建了一个新的进程,指定新的进程执行android.app.ActivityThread类。最后将表示这个新进程的ProcessRecord保存在mPidSelfLocked列表中,后面会用到。

             Step 5. Process.start

             这个函数定义在frameworks/base/core/java/android/os/Process.java文件中,这个函数我们就不看了,有 兴趣的读者可以自己研究一下。在这个场景中,它就是新建一个进程,然后导入android.app.ActivityThread这个类,然后执行它的 main函数。

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

    1. public final class ActivityThread {  
    2.       
    3.     ......  
    4.   
    5.     public static final void main(String[] args) {  
    6.   
    7.         ......  
    8.   
    9.         Looper.prepareMainLooper();  
    10.       
    11.         ......  
    12.   
    13.         ActivityThread thread = new ActivityThread();  
    14.         thread.attach(false);  
    15.   
    16.         ......  
    17.   
    18.         Looper.loop();  
    19.   
    20.         ......  
    21.   
    22.         thread.detach();  
    23.       
    24.         ......  
    25.     }  
    26. }  

            注意,执行到这里的时候,已经是在上一步创建的新进程里面了,即这里的进程是用来启动服务的,原来的主进程已经完成了它的命令,返回了。

            前面我们提到,在Android应用程序中,每一个进程对应一个ActivityThread实例,所以,这个函数会创建一个thread实例,然后调用ActivityThread.attach函数进一步处理。

            Step 7. ActivityThread.attach

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

    1. public final class ActivityThread {  
    2.       
    3.     ......  
    4.   
    5.     private final void attach(boolean system) {  
    6.           
    7.         ......  
    8.   
    9.         if (!system) {  
    10.   
    11.             ......  
    12.   
    13.             IActivityManager mgr = ActivityManagerNative.getDefault();  
    14.             try {  
    15.                 mgr.attachApplication(mAppThread);  
    16.             } catch (RemoteException ex) {  
    17.             }  
    18.         } else {  
    19.           
    20.             ......  
    21.   
    22.         }  
    23.   
    24.         ......  
    25.   
    26.     }  
    27.   
    28.     ......  
    29.   
    30. }  

             从Step 6中,这里传进来的参数system为false。成员变量mAppThread是一个ApplicationThread实例,我们在前面已经描述过这个实例的作用,它是用来辅助ActivityThread来执行一些操作的。

             调用ActivityManagerNative.getDefault函数得到ActivityManagerService的远程接口,即ActivityManagerProxy,接着调用它的attachApplication函数。

             Step 8. ActivityManagerProxy.attachApplication
             这个函数定义在frameworks/base/core/java/android/app/ActivityManagerNative.java文件中:

    1. class ActivityManagerProxy implements IActivityManager  
    2. {  
    3.     ......  
    4.   
    5.     public void attachApplication(IApplicationThread app) throws RemoteException  
    6.     {  
    7.         Parcel data = Parcel.obtain();  
    8.         Parcel reply = Parcel.obtain();  
    9.         data.writeInterfaceToken(IActivityManager.descriptor);  
    10.         data.writeStrongBinder(app.asBinder());  
    11.         mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0);  
    12.         reply.readException();  
    13.         data.recycle();  
    14.         reply.recycle();  
    15.     }  
    16.   
    17.     ......  
    18.   
    19. }  

            这个函数主要是将新进程里面的IApplicationThread实例通过Binder驱动程序传递给ActivityManagerService。

            Step 9. ActivityManagerService.attachApplication

            这个函数定义在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.           
    6.     public final void attachApplication(IApplicationThread thread)   
    7.     {  
    8.         synchronized (this) {  
    9.             int callingPid = Binder.getCallingPid();  
    10.             final long origId = Binder.clearCallingIdentity();  
    11.             attachApplicationLocked(thread, callingPid);  
    12.             Binder.restoreCallingIdentity(origId);  
    13.         }  
    14.     }  
    15.       
    16.     ......  
    17.   
    18. }  

             这里通过调用attachApplicationLocked函数进一步处理。

             Step 10. ActivityManagerService.attachApplicationLocked

             这个函数定义在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.   
    6.     private final boolean attachApplicationLocked(IApplicationThread thread,  
    7.             int pid) {  
    8.         // Find the application record that is being attached...  either via  
    9.         // the pid if we are running in multiple processes, or just pull the  
    10.         // next app record if we are emulating process with anonymous threads.  
    11.         ProcessRecord app;  
    12.         if (pid != MY_PID && pid >= 0) {  
    13.             synchronized (mPidsSelfLocked) {  
    14.                 app = mPidsSelfLocked.get(pid);  
    15.             }  
    16.         } else if (mStartingProcesses.size() > 0) {  
    17.             app = mStartingProcesses.remove(0);  
    18.             app.setPid(pid);  
    19.         } else {  
    20.             app = null;  
    21.         }  
    22.   
    23.         ......  
    24.   
    25.   
    26.         String processName = app.processName;  
    27.           
    28.         ......  
    29.   
    30.         app.thread = thread;  
    31.   
    32.         ......  
    33.           
    34.         boolean badApp = false;  
    35.   
    36.         ......  
    37.   
    38.         // Find any services that should be running in this process...  
    39.         if (!badApp && mPendingServices.size() > 0) {  
    40.             ServiceRecord sr = null;  
    41.             try {  
    42.                 for (int i=0; i<mPendingServices.size(); i++) {  
    43.                     sr = mPendingServices.get(i);  
    44.                     if (app.info.uid != sr.appInfo.uid  
    45.                         || !processName.equals(sr.processName)) {  
    46.                             continue;  
    47.                     }  
    48.   
    49.                     mPendingServices.remove(i);  
    50.                     i--;  
    51.                     realStartServiceLocked(sr, app);  
    52.                     didSomething = true;  
    53.                 }  
    54.             } catch (Exception e) {  
    55.   
    56.                 ......  
    57.   
    58.             }  
    59.         }  
    60.   
    61.         ......  
    62.   
    63.         return true;  
    64.     }  
    65.   
    66.     ......  
    67.   
    68. }  

            回忆一下在上面的Step 4中,以新进程的pid值作为key值保存了一个ProcessRecord在mPidsSelfLocked列表中,这里先把它取出来,存放在本地变量 app中,并且将app.processName保存在本地变量processName中。

            再回忆一下在上面的Step 3中,在成员变量mPendingServices中,保存了一个ServiceRecord,这里通过进程uid和进程名称将它找出来,然后通过realStartServiceLocked函数来进一步处理。

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

     

    1. class ActivityManagerProxy implements IActivityManager  
    2. {  
    3.     ......  
    4.   
    5.     private final void realStartServiceLocked(ServiceRecord r,  
    6.             ProcessRecord app) throws RemoteException {  
    7.           
    8.         ......  
    9.   
    10.         r.app = app;  
    11.           
    12.         ......  
    13.   
    14.         try {  
    15.   
    16.             ......  
    17.           
    18.             app.thread.scheduleCreateService(r, r.serviceInfo);  
    19.               
    20.             ......  
    21.   
    22.         } finally {  
    23.   
    24.             ......  
    25.   
    26.         }  
    27.   
    28.         ......  
    29.   
    30.     }  
    31.   
    32.     ......  
    33.   
    34. }  

            这里的app.thread是一个ApplicationThread对象的远程接口,它是在上面的Step 6创建ActivityThread对象时作为ActivityThread对象的成员变量同时创建的,然后在Step 9中传过来的。然后调用这个远程接口的scheduleCreateService函数回到原来的ActivityThread对象中执行启动服务的操 作。        

            Step 12. ApplicationThreadProxy.scheduleCreateService        

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

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

            这里通过Binder驱动程序回到新进程的ApplicationThread对象中去执行scheduleCreateService函数。

            Step 13. ApplicationThread.scheduleCreateService

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

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

            这里调用ActivityThread的queueOrSendMessage将一个CreateServiceData数据放到消息队列中去,并且分开这个消息。注意,这里已经是在上面Step 4创建的新进程中执行了。

            Step 14. ActivityThread.queueOrSendMessage

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

    1. public final class ActivityThread {  
    2.       
    3.     ......  
    4.   
    5.     private final void queueOrSendMessage(int what, Object obj) {  
    6.         queueOrSendMessage(what, obj, 0, 0);  
    7.     }  
    8.   
    9.     private final void queueOrSendMessage(int what, Object obj, int arg1, int arg2) {  
    10.         synchronized (this) {  
    11.             ......  
    12.             Message msg = Message.obtain();  
    13.             msg.what = what;  
    14.             msg.obj = obj;  
    15.             msg.arg1 = arg1;  
    16.             msg.arg2 = arg2;  
    17.             mH.sendMessage(msg);  
    18.         }  
    19.     }  
    20.   
    21.     ......  
    22.   
    23. }  

            这里调用成员变量mH的sendMessage函数进行消息分发。这里的mH的类型为H,它继承于Handler类。

            Step 15. H.sendMessage

            这个函数继承于Handle类的sendMessage函数中,定义在frameworks/base/core/java/android/os /Handler.java文件中。这个函数我们就不看了,有兴趣的读者可以自己研究一下。消息分发以后,就进入到H.handleMessage函数进 行处理了。

            Step 16. H.handleMessage

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

    1. public final class ActivityThread {  
    2.       
    3.     ......  
    4.   
    5.     private final class H extends Handler {  
    6.           
    7.         ......  
    8.   
    9.         public void handleMessage(Message msg) {  
    10.   
    11.             ......  
    12.   
    13.             switch (msg.what) {  
    14.   
    15.                 ......  
    16.   
    17.                 case CREATE_SERVICE:  
    18.                     handleCreateService((CreateServiceData)msg.obj);  
    19.                     break;  
    20.   
    21.                 ......  
    22.             }  
    23.   
    24.             ......  
    25.   
    26.         }  
    27.   
    28.         ......  
    29.   
    30.     }  
    31.   
    32.     ......  
    33.   
    34. }  

            这里要处理的消息是CREATE_SERVICE,它调用ActivityThread类的handleCreateService成员函数进一步处理。

            Step 17. ActivityThread.handleCreateService

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

    1. public final class ActivityThread {  
    2.       
    3.     ......  
    4.   
    5.     private final void handleCreateService(CreateServiceData data) {  
    6.         // If we are getting ready to gc after going to the background, well  
    7.         // we are back active so skip it.  
    8.         unscheduleGcIdler();  
    9.   
    10.         LoadedApk packageInfo = getPackageInfoNoCheck(  
    11.             data.info.applicationInfo);  
    12.         Service service = null;  
    13.         try {  
    14.             java.lang.ClassLoader cl = packageInfo.getClassLoader();  
    15.             service = (Service) cl.loadClass(data.info.name).newInstance();  
    16.         } catch (Exception e) {  
    17.             if (!mInstrumentation.onException(service, e)) {  
    18.                 throw new RuntimeException(  
    19.                     "Unable to instantiate service " + data.info.name  
    20.                     + ": " + e.toString(), e);  
    21.             }  
    22.         }  
    23.   
    24.         try {  
    25.             if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);  
    26.   
    27.             ContextImpl context = new ContextImpl();  
    28.             context.init(packageInfo, null, this);  
    29.   
    30.             Application app = packageInfo.makeApplication(false, mInstrumentation);  
    31.             context.setOuterContext(service);  
    32.             service.attach(context, this, data.info.name, data.token, app,  
    33.                 ActivityManagerNative.getDefault());  
    34.             service.onCreate();  
    35.             mServices.put(data.token, service);  
    36.             try {  
    37.                 ActivityManagerNative.getDefault().serviceDoneExecuting(  
    38.                     data.token, 0, 0, 0);  
    39.             } catch (RemoteException e) {  
    40.                 // nothing to do.  
    41.             }  
    42.               
    43.         } catch (Exception e) {  
    44.             if (!mInstrumentation.onException(service, e)) {  
    45.                 throw new RuntimeException(  
    46.                     "Unable to create service " + data.info.name  
    47.                     + ": " + e.toString(), e);  
    48.             }  
    49.         }  
    50.     }  
    51.   
    52.     ......  
    53.   
    54. }  

            这里的data.info.name就是自定义的服务类shy.luo.ashmem.Server了。

            Step 18. ClassLoader.loadClass

            这一步实现在上面的ActivityThread.handleCreateService函数中:

    1. java.lang.ClassLoader cl = packageInfo.getClassLoader();  
    2. service = (Service) cl.loadClass(data.info.name).newInstance();  

            Step 19. Obtain Service

            这一步也是实现在上面的ActivityThread.handleCreateService函数中。上面通过 ClassLoader.loadClass来导入自定义的服务类shy.luo.ashmem.Server并且创建它的一个实例后,就通过强制类型转 换得到一个Service类实例。前面我们说过,自己的服务类必须要继承于Service类,这里就体现出来了为什么要这样做了。

            Step 20. Service.onCreate

            这一步继续实现在上面的ActivityThread.handleCreateService函数中:

    1. service.onCreate();  

            因为这里的service实际上是一个shy.luo.ashmem.Server类实例,因此,这里就是执行shy.luo.ashmem.Server类的onCreate函数了:

    1. public class Server extends Service {  
    2.       
    3.     ......  
    4.   
    5.     @Override  
    6.     public void onCreate() {  
    7.         ......  
    8.   
    9.     }  
    10.   
    11.     ......  
    12. }  

            至此,这个自定义的服务就启动起来了。

            这样,Android系统在新进程中启动服务的过程就分析完成了,虽然很复杂,但是条理很清晰。它通过三次Binder进程间通信完成了服务的启动过程,分别是:

            一. Step 1至Step 7,从主进程调用到ActivityManagerService进程中,完成新进程的创建;

            二. Step 8至Step 11,从新进程调用到ActivityManagerService进程中,获取要在新进程启动的服务的相关信息;

            三. Step 12至Step 20,从ActivityManagerService进程又回到新进程中,最终将服务启动起来。

            学习完Android系统在新进程中启动服务的过程后,希望读者对Android系统的Service有一个深刻的理解。在编写Android应用程序 的时候,尽量把一些计算型的逻辑以Service在形式来实现,使得这些耗时的计算能在一个独立的进程中进行,这样就能保持主进程流畅地响应界面事件,提 高用户体验。

    老罗的新浪微博:http://weibo.com/shengyangluo,欢迎关注!

     
     

     

  • 相关阅读:
    ansible-playbook基础
    ansible-playbook批量安装tomcat8版本
    linux
    PostgreSQL View(视图)
    PostgreSQL TRUNCATE TABLE
    PostgreSQL ALTER TABLE 命令
    redis主从环境搭建
    PostgreSQL 约束
    解决Chrome中Software Reporter Tool占CPU用过高
    C++标准模板库(STL)简介及应用
  • 原文地址:https://www.cnblogs.com/xgjblog/p/3928796.html
Copyright © 2011-2022 走看看