標籤:
一、Android系統服務
Android提供了很多系統服務:如ActivityManger,PowerManger,WindowManger,WifiManger等等。
這些服務都是系統啟動開始就一直常駐的,如果app需要使用相應的系統服務(如擷取當前wifi的狀態),則需要通過Binder去訪問系統服務。
例如:WifiManager mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
二、Binder處理序間通訊
app間如何通過binder進行進程間通訊(通常是一個app要使用另一個app提供的服務),見android bindService() 和 Android AIDL
通過查看源碼我們可以看到,一般情況下,系統服務通過AIDL定義開放介面。整體調用關係和app處理序間通訊是一樣的。
三、將服務設定為系統服務
一般app提供的service,必須要手動啟動或者開機啟動,且app層級的service在資源緊缺時也比較容易被殺死。
那麼我們能不能將哪些需要常駐的服務就設定為系統服務呢?
步驟:
1.我們仿照原生的系統服務(如ActivityManger,PowerManger,WindowManger,WifiManger),註冊相關的服務。
比如,我們要新註冊的系統服務就叫做DemoSystemService。
我們找到原生系統服務註冊的地方,SystemServer.java的startOtherServices()方法,加上如下代碼,完成對DemoSystemService的註冊
1 try {2 Slog.i(TAG, "DemoSystem service");3 ServiceManager.addService("demosystemservice",4 new DemoSystemManager(context));5 } catch (Throwable e) {6 reportWtf("starting DemoSystemService", e);7 } 2.按照AIDL的設計要求,DemoSystemService必須提供相應的AIDL檔案,並實現AIDL的標準介面
先是AIDL標準介面的設定
package android.app; interface IDemoSystemManager { boolean getState(); void setState(boolean state);}
然後是具體系統服務的內容,符合AIDL標準介面
package com.android.server; import android.app.IDemoSystemManager; import android.util.Log; import android.content.Context; public class DemoSystemManager extends IDemoSystemManager.Stub { private static final String TAG = "DemoSystemManager"; private Context mContext; private boolean state = False; public DemoSystemManager(Context context){ mContext = context; }
public boolean getState() { Log.d(TAG,"[getState] state : "+state); return state; } public void setState(boolean state) { Log.d(TAG,"[setState] state : "+state); return 0; }} 3.到此,服務端就已經寫好了。下面是用戶端如何使用服務。
import android.hardware.DemoSystemManger; private IDemoSystemManager mDemoSystemManager; mDemoSystemManager = IDemoSystemManager.Stub.asInterface(ServiceManager.getService(“demosystemservice”));
然後就可以直接使用mDemoSystemManger了
4.其他要配置的內容a.將AIDL檔案放到編譯android.mk中
在frameworks/base/Android.mk檔案中的LOCAL_SRC_FILES增加aidl的聲明:@@ -112,6 +112,7 @@ LOCAL_SRC_FILES += core/java/android/app/backup/IFullBackupRestoreObserver.aidl core/java/android/app/backup/IRestoreObserver.aidl core/java/android/app/backup/IRestoreSession.aidl + core/java/android/app/IDemoSystemManger.aidl \ core/java/android/bluetooth/IBluetooth.aidl core/java/android/bluetooth/IBluetoothA2dp.aidl \
b.android5.0之後,如果要建立系統服務,還需要添加許可權(此為SELinux帶來的影響,SELinux相關內容可網上去查其他文章)
在/device/sprd/scx35/sepolicy/service_contexts檔案中,添加許可權atchannel u:object_r:radio_service:s0fm u:object_r:mediaserver_service:s0sprdsimphonebook u:object_r:radio_service:s0sprd_phone u:object_r:radio_service:s0security u:object_r:system_server_service:s0board_score u:object_r:system_server_service:s0phasechecknative u:object_r:system_server_service:s0demosystemservice u:object_r:system_server_service:s0
註:本文中的例子是一個非常簡單的系統服務,如果希望再看下相對複雜點的例子,可以看下面參考文章中的例子,此例子更加生動,代碼結構也更加合理。
參考文章:
[android]Framework新增系統服務
Android的系統服務一覽
建立android系統服務