標籤:
Android系統服務大致分為三大類:本地守護進程、Native系統服務和Java系統服務。如所示:
本地守護進程
init進程根據init.rc檔案中的定義,啟動本地守護進程。這些進程會常駐在系統中,有的只會啟動一次,有的如果退出了,還會被init啟動。具體的啟動方式就在init.rc中定義。
下面大體列舉幾個守護進程及其功能。
| 守護進程 |
功能 |
| vold |
管理存放裝置,自動安裝存放裝置,將裝置分區格式化 |
| netd |
管理藍芽、wifi、usb等各種網路連接 |
| installd |
負責安裝及卸載軟體包,確認軟體包的完整性 |
| rild |
接收來自於phone應用程式或其他用戶端程式發出的調製解調控制請求,並傳遞給數據機 |
| adbd |
提供可以調試Android的環境 |
| servicemanager |
binder通訊大管家 |
| surfaceflinger |
負責android系統的UI圖形顯示 |
| mediaserver |
負責播放音頻、視頻,camera拍照錄影 |
Native系統服務
由c++語言編寫,運行在本地守護進程中。比如mediaserver守護進程中就包含AudioFlinger、MediaPlayerService、CameraService、AudioPolicyService和SoundTriggerHwService等服務。在
mediaserver進程的main函數中,初始化這些服務的執行個體,代碼如下:
int main(int argc __unused, char** argv){ ... sp<ProcessState> proc(ProcessState::self()); sp<IServiceManager> sm = defaultServiceManager(); ALOGI("ServiceManager: %p", sm.get()); AudioFlinger::instantiate(); MediaPlayerService::instantiate(); CameraService::instantiate(); AudioPolicyService::instantiate(); SoundTriggerHwService::instantiate(); ... ProcessState::self()->startThreadPool(); IPCThreadState::self()->joinThreadPool();}
在所屬進程初始化的時候會將Native系統服務註冊到ServiceManager中。這樣,其他的應用或服務就可以通過binder機制調用Native系統服務了。
當然,我們也可以自己開發一個Native系統服務,實現其Binder介面,這樣Native層的其他應用或服務就可以調用該服務了。
如果我們開發的Native系統服務想提供給Java層應用使用,就需要實現一個Java介面,然後通過JNI調用Native系統服務。
Java系統服務
由Java語言編寫,大部分運行在system_server進程中。每個系統服務都以線程的形態運行,等待應用程式發出的請求,然後對請求進程處理,再講結果返回給應用程式。
這部分系統服務又可以分為兩種:Java核心系統服務和Java硬體系統服務。
Java核心系統服務是Android系統正常運轉的基礎,包括大家所熟知的AMS、WMS、PMS等。
Java硬體服務是為應用提供硬體控制服務,如電話語音、wifi服務、PowerManagerService等。
下面羅列了運行在system_server中的系統服務,按字母排序。
AccessibilityManagerService 截獲使用者輸入,並根據輸入給使用者一些額外的反饋,起到輔助效果的服務
AccountManagerService 管理裝置中所有帳號的服務,包括帳號、密碼、授權管理功能
ActivityManagerService 管理所有組件的服務,安卓系統的核心服務 AlarmManagerService 管理鬧鐘的服務
AppWidgetService 管理APP widgets的工作,包括載入、刪除、布局等
AssetAtlasService 將一些系統圖片資源合并成一個紋理圖傳給GPU達到硬體加速的效果的服務
AudioService 管理音訊服務
BackupManagerService 管理備份和應用資料的服務
BatteryService 管理電池的服務
BluetoothManagerService 管理系統藍芽的服務
CertBlacklister 更新系統SSL認證的公用秘鑰和序號黑名單的服務
ClipboardService 管理系統剪貼簿的服務
CommonTimeManagementService 管理公用時間配置的服務
ConnectivityService 管理網路連接的服務
ContentService 管理系統資料更新通知的服務,和ContentProvider密切相關
CountryDetectorService 檢測當前系統所屬國家的服務
DevicePolicyManagerService 管理系統裝置配置的服務
DeviceStorageMonitorService 管理系統儲存空間的服務,當儲存空間小於某個閾值時,會發出警告廣播
DiskStateService 管理系統儲存空間統計的服務
DisplayManagerService 管理顯示裝置的服務
DreamManagerService 管理螢幕保護裝置的服務
DropBoxManagerService 產生和管理系統運行中記錄檔的服務
EntropyMixer 載入和儲存隨機資訊的服務
IdleMaintenanceService 管理系統在空閑時執行維護任務的服務
InputManagerService 管理觸屏輸入的服務
InputMethodManagerService 管理系統IME的服務
LightsService 管理光感應器的服務
LocationManagerService 管理定位和位置的服務
LockSettingsService 管理系統鎖屏設定的服務
MountService 管理系統存放裝置掛載和卸載的服務
NetWorkManagementService 管理系統網路的服務
NetWorkPolicyManagerService 管理網路連接策略的服務
NetWorkStatsService 管理網路連接狀態的服務
NetWorkTimeUpdateService 根據網路時間更新本地時間的服務
NotificationManagerService 管理系統通知的服務
PackageManagerService 管理應用程式套件的服務
PowerManagerService 管理系統電源的服務
PrintManagerService 管理列印的服務
RecognitionManagerService 管理身份識別的服務
SamplingProfilerService 記錄和分析系統啟動效能的服務
SchedulingPolicyService 管理系統調度策略的服務
SearchManagerServcie 管理系統搜尋功能的服務
SerialServie 管理系統串口裝置的服務
StatusBarManagerService 管理系統狀態列的服務
TelephonyRegistry 監聽和管理通話事件和狀態的服務
TextServicesManagerService 文本拼字檢查的服務
UiModeManagerService 設定和管理系統UI模式的服務
UsbService 管理USB已連線的服務
UserManagerService 管理系統使用者身份資訊的服務
VibratorService 管理系統震動器的服務
WallpaperManagerService 管理系統案頭背景牆紙的服務
WifiP2pService 管理Wifi點對點連接的服務
WifiService 管理系統Wifi裝置的服務
WindowManagerService 管理視窗的服務,安卓系統的核心服務
Java系統服務的實現
從在android5.1.1中,Java Service一般都會繼承一個虛類SystemService,在其中定義了兩個介面onStart和onBootPhase。
- onStart() :Java Service啟動的時候會回調該函數。
- onBootPhase() : 系統啟動的各個階段會回調該函數。
這樣,啟動服務就很簡單了:
mSystemServiceManager.startService(xxxxxxService.class);
我們繼續看一下startService的實現:
public class SystemServiceManager { // 儲存所有SystemService private final ArrayList<SystemService> mServices = new ArrayList<SystemService>(); public SystemService startService(String className) { final Class<SystemService> serviceClass; try { //調用JVM載入className指定的類,會執行該類的靜態程式碼片段 serviceClass = (Class<SystemService>)Class.forName(className); } catch (ClassNotFoundException ex) { ... } ... mServices.add(service); // 添加該service try { service.onStart(); // 回調該service的onStart方法 } catch (RuntimeException ex) { ... } ... }}
下面看一下onBootPhase回調方法。
在system啟動的一些階段,系統會調用如下代碼,主動回調SystemService的onBootPhase方法。
mSystemServiceManager.startBootPhase(SystemService.PHASE_XXXXXX);public class SystemServiceManager { public void startBootPhase(final int phase) { // 階段值會隨著系統啟動的進行越來越大,因此下一個階段值肯定要大於當前階段 if (phase <= mCurrentPhase) { throw new IllegalArgumentException("Next phase must be larger than previous"); } mCurrentPhase = phase; //儲存當前階段 // 遍曆所有的SystemService,並回調它的onBootPhase方法。 final int serviceLen = mServices.size(); for (int i = 0; i < serviceLen; i++) { final SystemService service = mServices.get(i); try { service.onBootPhase(mCurrentPhase); // 將階段值也傳進去 } catch (Exception ex) { ... } } } }
PHASE_XXXXXX指示了各個不同的啟動階段,定義如下:
public abstract class SystemService { public static final int PHASE_WAIT_FOR_DEFAULT_DISPLAY = 100; public static final int PHASE_LOCK_SETTINGS_READY = 480; public static final int PHASE_SYSTEM_SERVICES_READY = 500; public static final int PHASE_ACTIVITY_MANAGER_READY = 550; public static final int PHASE_THIRD_PARTY_APPS_CAN_START = 600; public static final int PHASE_BOOT_COMPLETED = 1000;}
所以,在onBootPhase(int phase)中,我們可以根據phase中指示的啟動階段,做不同的操作!在自己設計新的系統服務時,這個很重要。因為一些操作需要系統內容的支援,有了這個回呼函數及phase參數,我們就可以在合適的階段做合適的操作了。
另外,Java系統服務中一般還會實現一個方法:systemReady()。該方法在SystemServer.java–>startOtherServices()調用:
final XXXService xxxService;mActivityManagerService.systemReady(new Runnable() { @Override public void run() { try { if (xxxService != null) xxxService.systemReady(); } catch (Throwable e) { reportWtf("making XXX Service ready", e); } ... }}
在[Android5.1]ActivityManagerService啟動過程分析中,我們知道AMS的systemReady方法會回調這個Runnable,上述代碼就會執行。
注意:Java系統服務的onStart、onBootPhase、systemReady等方法,都運行在system_server主線程中。建議建立一個線程來處理複雜、耗時操作。
Java系統服務Binder通訊
上面講了Java系統服務的實現,隨之而來的一個問題是,其他服務或應用怎麼調用Java系統服務的功能?當然是通過Binder通訊。
下面就講一下Java系統服務的Binder服務實現。假設服務名為ExampleService。
首先,需要建立和實現三個檔案:
frameworks/base/core/java/android/app/IExample.aidl
frameworks/base/core/java/android/app/Example.java
frameworks/base/services/core/java/android/server/ExampleService.java
frameworks/base/core/java/android/app/IExample.aidl代碼如下:
interface IExample { boolean helloWorld(String str);}
frameworks/base/core/java/android/app/Example.java代碼如下:
class Example { private final IExample mService; Example(Context context, IExample service) { mService = service; } public boolean helloWorld(String str) { try { return mService.helloWorld(str); } catch(RemoteException e) { return null; } }}
frameworks/base/services/core/java/android/server/ExampleService.java代碼如下:
class ExampleService extends SystemService { private Context mContext; public ExampleService(Context context) { super(context); mContext = context; } @Override public void onStart() { publishBinderService(Context.EXAMPLE_SERVICE, new BinderService()); } @Override public void onBootPhase(int phase) { if (phase == PHASE_SYSTEM_SERVICES_READY) { ... } if (phase == PHASE_ACTIVITY_MANAGER_READY) { ... } if (phase == PHASE_BOOT_COMPLETED) { ... } ... } public void systemReady() { ... } class BinderService extend IExample.Stub { @Override boolean helloWorld(String str) { ... } } }
其次,修改如下檔案的代碼:
frameworks/base/services/java/com/android/server/SystemServer.java
frameworks/base/core/java/android/content/Context.java
frameworks/base/core/java/android/app/SystemServiceRegistry.java
- frameworks/base/services/java/com/android/server/SystemServer.java修改如下:
import com.android.server.ExampleService;public final class SystemServer { ExampleService mExampleService = null; ... private void startOtherServices() { ... mExampleService = mSystemServiceManager.startService(ExampleService.class); ... try { if (mExampleService != null) mExampleService.systemReady(); } catch (Throwable e) { reportWtf("making Example Service ready", e); } ... }
- frameworks/base/core/java/android/content/Context.java修改如下:
public abstract class Context { ... public static final String EXAMPLE_SERVICE = "example"; ...}
- frameworks/base/core/java/android/app/SystemServiceRegistry.java修改如下:
final class SystemServiceRegistry { ... registerService(Context.EXAMPLE_SERVICE, Example.class, new CachedServiceFetcher<Example>() { @Override public Example createService(ContextImpl ctx) { IBinder b = ServiceManager.getService(Context.EXAMPLE_SERVICE); IExample service = IExample.Stub.asInterface(b); if (service == null) { Log.wtf(TAG, "Failed to get Example Service."); } return new Example(ctx.getOuterContext(),service); }}); ...}
最後,其他應用或服務通過binder調用ExampleService的helloWorld方法,代碼如下:
import android.app.Example;class Client { static Example mService; mService = (Example) context.getSystemService(Context.EXAMPLE_SERVICE); mService.helloWorld(str);}
Android 系統服務