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, 00);  
    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, nullthis);  
    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, 000);  
    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在形式来实现,使得这些耗时的计算能在一个独立的进程中进行,这样就能保持主进程流畅地响应界面事件,提高用户体验。

     --------------------------------------------------------------------

    PS: 欢迎关注公众号"Devin说",会不定期更新Java相关技术知识。

    --------------------------------------------------------------------

    转自:http://blog.csdn.net/luoshengyang/article/details/6677029

  • 相关阅读:
    DRUPAL-PSA-CORE-2014-005 && CVE-2014-3704 Drupal 7.31 SQL Injection Vulnerability /includes/database/database.inc Analysis
    WDCP(WDlinux Control Panel) mysql/add_user.php、mysql/add_db.php Authentication Loss
    Penetration Testing、Security Testing、Automation Testing
    Tomcat Server Configuration Automation Reinforcement
    Xcon2014 && Geekpwn2014
    phpMyadmin /scripts/setup.php Remote Code Injection && Execution CVE-2009-1151
    Linux System Log Collection、Log Integration、Log Analysis System Building Learning
    The Linux Process Principle,NameSpace, PID、TID、PGID、PPID、SID、TID、TTY
    Windows Management Instrumentation WMI Security Technology Learning
    IIS FTP Server Anonymous Writeable Reinforcement, WEBDAV Anonymous Writeable Reinforcement(undone)
  • 原文地址:https://www.cnblogs.com/devinzhang/p/2309733.html
Copyright © 2011-2022 走看看