午夜视频在线网站,日韩视频精品在线,中文字幕精品一区二区三区在线,在线播放精品,1024你懂我懂的旧版人,欧美日韩一级黄色片,一区二区三区在线观看视频

分享

Android系統(tǒng)在新進(jìn)程中啟動自定義服務(wù)過程(startService)的原理分析

 lifei_szdz 2013-05-19

在編寫Android應(yīng)用程序時,我們一般將一些計算型的邏輯放在一個獨立的進(jìn)程來處理,這樣主進(jìn)程仍然可以流暢地響應(yīng)界面事件,提高用戶體驗。Android系統(tǒng)為我們提供了一個Service類,我們可以實現(xiàn)一個以Service為基類的服務(wù)子類,在里面實現(xiàn)自己的計算型邏輯,然后在主進(jìn)程通過startService函數(shù)來啟動這個服務(wù)。在本文中,將詳細(xì)分析主進(jìn)程是如何通過startService函數(shù)來在新進(jìn)程中啟動自定義服務(wù)的。

        在主進(jìn)程調(diào)用startService函數(shù)時,會通過Binder進(jìn)程間通信機制來通知ActivitManagerService來創(chuàng)建新進(jìn)程,并且啟動指定的服務(wù)。在Android系統(tǒng)中,Binder進(jìn)程間通信機制使用非常廣泛,因此,希望讀者在繼續(xù)閱讀下面的內(nèi)容之前,對Android系統(tǒng)和Binder進(jìn)程間通信機制有一定的了解,具體可以參考前面Android進(jìn)程間通信(IPC)機制Binder簡要介紹和學(xué)習(xí)計劃一文。

        關(guān)于startService的具體用法,可以參考前面Android系統(tǒng)匿名共享內(nèi)存Ashmem(Anonymous Shared Memory)簡要介紹和學(xué)習(xí)計劃一文中用到的實例,它是Activity類的一個成員函數(shù):

  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系統(tǒng)它所要啟動的服務(wù)的名字:

  1. <manifest xmlns:android="http://schemas./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”對應(yīng)的服務(wù)類為shy.luo.ashmem.Server,下面語句:

  1. startService(new Intent("shy.luo.ashmem.server"));  
         就表示要在一個新的進(jìn)程中啟動shy.luo.ashmem.Server這個服務(wù)類,它必須繼承于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成員函數(shù)是如何實現(xiàn)的。

        先來看看Activity的類圖:


        從圖中可以看出,Activity繼承了ContextWrapper類,而在ContextWrapper類中,實現(xiàn)了startService函數(shù)。在ContextWrapper類中,有一個成員變量mBase,它是一個ContextImpl實例,而ContextImpl類和ContextWrapper類一樣繼承于Context類,ContextWrapper類的startService函數(shù)最終過調(diào)用ContextImpl類的startService函數(shù)來實現(xiàn)。這種類設(shè)計方法在設(shè)計模式里面,就稱之為裝飾模式(Decorator),或者包裝模式(Wrapper)。

        在ContextImpl類的startService類,最終又調(diào)用了ActivityManagerProxy類的startService來實現(xiàn)啟動服務(wù)的操作,看到這里的Proxy關(guān)鍵字,回憶一下前面Android系統(tǒng)進(jìn)程間通信Binder機制在應(yīng)用程序框架層的Java接口源代碼分析這篇文章,就會知道ActivityManagerProxy是一個Binder對象的遠(yuǎn)程接口了,而這個Binder對象就是我們前面所說的ActivityManagerService了。

        這個ActivityManagerService類實現(xiàn)在frameworks/base/services/java/com/android/server/am/ActivityManagerService.java文件中,它是Binder進(jìn)程間通信機制中的Server角色,它是隨機啟動的。隨機啟動的Server是在frameworks/base/services/java/com/android/server/SystemServer.java文件里面進(jìn)行啟動的,我們來看一下ActivityManagerService啟動相關(guān)的代碼:

  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. }  
          首先是調(diào)用ActivityManagerService.main函數(shù)來創(chuàng)建一個ActivityManagerService實例,然后通過調(diào)用ActivityManagerService.setSystemProcess函數(shù)把這個Binder實例添加Binder進(jìn)程間通信機制的守護(hù)進(jìn)程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函數(shù)中,它定義在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. }  
         參數(shù)service是一個Intent實例,它里面指定了要啟動的服務(wù)的名稱,就是前面我們所說的“shy.luo.ashmem.server”了。

         參數(shù)caller是一個IApplicationThread實例,它是一個在主進(jìn)程創(chuàng)建的一個Binder對象。在Android應(yīng)用程序中,每一個進(jìn)程都用一個ActivityThread實例來表示,而在ActivityThread類中,有一個成員變量mAppThread,它是一個ApplicationThread實例,實現(xiàn)了IApplicationThread接口,它的作用是用來輔助ActivityThread類來執(zhí)行一些操作,這個我們在后面會看到它是如何用來啟動服務(wù)的。

        參數(shù)resolvedType是一個字符串,它表示service這個Intent的MIME類型,它是在解析Intent時用到的。在這個例子中,我們沒有指定這個Intent 的MIME類型,因此,這個參數(shù)為null。

        ActivityManagerProxy類的startService函數(shù)把這三個參數(shù)寫入到data本地變量去,接著通過mRemote.transact函數(shù)進(jìn)入到Binder驅(qū)動程序,然后Binder驅(qū)動程序喚醒正在等待Client請求的ActivityManagerService進(jìn)程,最后進(jìn)入到ActivityManagerService的startService函數(shù)中。

        ActivityManagerService的startService函數(shù)的處理流程如下圖所示:


 點擊查看大圖

          在這個序列圖中,一共有20個步驟,下面說明每一步。

         Step 1. ActivityManagerService.startService

         這個函數(shù)定義在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. }  
         這里的參數(shù)caller、service和resolvedType分別對應(yīng)ActivityManagerProxy.startService傳進(jìn)來的三個參數(shù)。

         Step 2. ActivityManagerService.startServiceLocked
         這個函數(shù)同樣定義在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. }  
        函數(shù)首先通過retrieveServiceLocked來解析service這個Intent,就是解析前面我們在AndroidManifest.xml定義的Service標(biāo)簽的intent-filter相關(guān)內(nèi)容,然后將解析結(jié)果放在res.record中,然后繼續(xù)調(diào)用bringUpServiceLocked進(jìn)一步處理。

        Step 3. ActivityManagerService.bringUpServiceLocked
        這個函數(shù)同樣定義在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標(biāo)簽時指定的android:process屬性值了,即“.Server”。

        接著調(diào)用startProcessLocked函數(shù)來創(chuàng)建一個新的進(jìn)程,以便加載自定義的Service類。最后將這個ServiceRecord保存在成員變量mPendingServices列表中,后面會用到。

        Step 4. ActivityManagerService.startProcessLocked

        這個函數(shù)同樣定義在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. }  

         這里調(diào)用Process.start函數(shù)創(chuàng)建了一個新的進(jìn)程,指定新的進(jìn)程執(zhí)行android.app.ActivityThread類。最后將表示這個新進(jìn)程的ProcessRecord保存在mPidSelfLocked列表中,后面會用到。

         Step 5. Process.start

         這個函數(shù)定義在frameworks/base/core/java/android/os/Process.java文件中,這個函數(shù)我們就不看了,有興趣的讀者可以自己研究一下。在這個場景中,它就是新建一個進(jìn)程,然后導(dǎo)入android.app.ActivityThread這個類,然后執(zhí)行它的main函數(shù)。

         Step 6. ActivityThread.main
         這個函數(shù)定義在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. }  
        注意,執(zhí)行到這里的時候,已經(jīng)是在上一步創(chuàng)建的新進(jìn)程里面了,即這里的進(jìn)程是用來啟動服務(wù)的,原來的主進(jìn)程已經(jīng)完成了它的命令,返回了。

        前面我們提到,在Android應(yīng)用程序中,每一個進(jìn)程對應(yīng)一個ActivityThread實例,所以,這個函數(shù)會創(chuàng)建一個thread實例,然后調(diào)用ActivityThread.attach函數(shù)進(jìn)一步處理。

        Step 7. ActivityThread.attach

        這個函數(shù)定義在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中,這里傳進(jìn)來的參數(shù)system為false。成員變量mAppThread是一個ApplicationThread實例,我們在前面已經(jīng)描述過這個實例的作用,它是用來輔助ActivityThread來執(zhí)行一些操作的。

         調(diào)用ActivityManagerNative.getDefault函數(shù)得到ActivityManagerService的遠(yuǎn)程接口,即ActivityManagerProxy,接著調(diào)用它的attachApplication函數(shù)。

         Step 8. ActivityManagerProxy.attachApplication
         這個函數(shù)定義在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. }  

        這個函數(shù)主要是將新進(jìn)程里面的IApplicationThread實例通過Binder驅(qū)動程序傳遞給ActivityManagerService。

        Step 9. ActivityManagerService.attachApplication

        這個函數(shù)定義在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. }  

         這里通過調(diào)用attachApplicationLocked函數(shù)進(jìn)一步處理。

         Step 10. ActivityManagerService.attachApplicationLocked

         這個函數(shù)定義在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中,以新進(jìn)程的pid值作為key值保存了一個ProcessRecord在mPidsSelfLocked列表中,這里先把它取出來,存放在本地變量app中,并且將app.processName保存在本地變量processName中。

        再回憶一下在上面的Step 3中,在成員變量mPendingServices中,保存了一個ServiceRecord,這里通過進(jìn)程uid和進(jìn)程名稱將它找出來,然后通過realStartServiceLocked函數(shù)來進(jìn)一步處理。

        Step 11. ActivityManagerService.realStartServiceLocked
        這個函數(shù)定義在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對象的遠(yuǎn)程接口,它是在上面的Step 6創(chuàng)建ActivityThread對象時作為ActivityThread對象的成員變量同時創(chuàng)建的,然后在Step 9中傳過來的。然后調(diào)用這個遠(yuǎn)程接口的scheduleCreateService函數(shù)回到原來的ActivityThread對象中執(zhí)行啟動服務(wù)的操作。        

        Step 12. ApplicationThreadProxy.scheduleCreateService        

        這個函數(shù)定義在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驅(qū)動程序回到新進(jìn)程的ApplicationThread對象中去執(zhí)行scheduleCreateService函數(shù)。

        Step 13. ApplicationThread.scheduleCreateService

        這個函數(shù)定義在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. }  
        這里調(diào)用ActivityThread的queueOrSendMessage將一個CreateServiceData數(shù)據(jù)放到消息隊列中去,并且分開這個消息。注意,這里已經(jīng)是在上面Step 4創(chuàng)建的新進(jìn)程中執(zhí)行了。

        Step 14. ActivityThread.queueOrSendMessage

        這個函數(shù)定義在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. }  

        這里調(diào)用成員變量mH的sendMessage函數(shù)進(jìn)行消息分發(fā)。這里的mH的類型為H,它繼承于Handler類。

        Step 15. H.sendMessage

        這個函數(shù)繼承于Handle類的sendMessage函數(shù)中,定義在frameworks/base/core/java/android/os/Handler.java文件中。這個函數(shù)我們就不看了,有興趣的讀者可以自己研究一下。消息分發(fā)以后,就進(jìn)入到H.handleMessage函數(shù)進(jìn)行處理了。

        Step 16. H.handleMessage

        這個函數(shù)定義在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,它調(diào)用ActivityThread類的handleCreateService成員函數(shù)進(jìn)一步處理。

        Step 17. ActivityThread.handleCreateService

        這個函數(shù)定義在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就是自定義的服務(wù)類shy.luo.ashmem.Server了。

        Step 18. ClassLoader.loadClass

        這一步實現(xiàn)在上面的ActivityThread.handleCreateService函數(shù)中:

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

        這一步也是實現(xiàn)在上面的ActivityThread.handleCreateService函數(shù)中。上面通過ClassLoader.loadClass來導(dǎo)入自定義的服務(wù)類shy.luo.ashmem.Server并且創(chuàng)建它的一個實例后,就通過強制類型轉(zhuǎn)換得到一個Service類實例。前面我們說過,自己的服務(wù)類必須要繼承于Service類,這里就體現(xiàn)出來了為什么要這樣做了。

        Step 20. Service.onCreate

        這一步繼續(xù)實現(xiàn)在上面的ActivityThread.handleCreateService函數(shù)中:

  1. service.onCreate();  
        因為這里的service實際上是一個shy.luo.ashmem.Server類實例,因此,這里就是執(zhí)行shy.luo.ashmem.Server類的onCreate函數(shù)了:

  1. public class Server extends Service {  
  2.       
  3.     ......  
  4.   
  5.     @Override  
  6.     public void onCreate() {  
  7.         ......  
  8.   
  9.     }  
  10.   
  11.     ......  
  12. }  
        至此,這個自定義的服務(wù)就啟動起來了。

        這樣,Android系統(tǒng)在新進(jìn)程中啟動服務(wù)的過程就分析完成了,雖然很復(fù)雜,但是條理很清晰。它通過三次Binder進(jìn)程間通信完成了服務(wù)的啟動過程,分別是:

        一. Step 1至Step 7,從主進(jìn)程調(diào)用到ActivityManagerService進(jìn)程中,完成新進(jìn)程的創(chuàng)建;

        二. Step 8至Step 11,從新進(jìn)程調(diào)用到ActivityManagerService進(jìn)程中,獲取要在新進(jìn)程啟動的服務(wù)的相關(guān)信息;

        三. Step 12至Step 20,從ActivityManagerService進(jìn)程又回到新進(jìn)程中,最終將服務(wù)啟動起來。

        學(xué)習(xí)完Android系統(tǒng)在新進(jìn)程中啟動服務(wù)的過程后,希望讀者對Android系統(tǒng)的Service有一個深刻的理解。在編寫Android應(yīng)用程序的時候,盡量把一些計算型的邏輯以Service在形式來實現(xiàn),使得這些耗時的計算能在一個獨立的進(jìn)程中進(jìn)行,這樣就能保持主進(jìn)程流暢地響應(yīng)界面事件,提高用戶體驗。

老羅的新浪微博:http://weibo.com/shengyangluo,歡迎關(guān)注!

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多