Android中的系統服務(代理模式)
一,系統啟動
Android裝置的開機流程總得來分可以分為三部分:
載入載入程式
載入程式bootloader是開機執行的第一個小程式,因此它是針對特定的主機板與晶片的。bootloader有很多種,可以使用比較流行的如redboot、uboot、ARMBoot等,也可以開發自己的載入程式,它不是Android作業系統的一部分。載入程式也是OEM廠商或者運營商加鎖和限制的地方。
載入程式初始化硬體裝置、建立儲存器空間的對映等軟體執行時所需要的最小環境;載入Linux核心映象檔案(本文只針對Android、Linux)到RAM中某個地址處執行,此時載入程式的控制權就交給了核心。這些對於執行核心是必要的,為了達到特殊的目標,載入程式可以根據配置引數或者輸入資料設定核心。
說明:加電後,CPU將先執行bootloader程式,此處有三種選擇:
a) 啟動到fastboot,即命令或SD卡燒寫模式,不載入核心及檔案系統,此處可以進行工廠模式的燒寫
b) 啟動到recovery模式,載入recovery.img,recovery.img包含核心,基本的檔案系統,用於工程模式的燒寫
c) 開機按Power,正常啟動系統,載入boot.img,boot.img包含核心,基本檔案系統,用於正常啟動手機(以下只分析正常啟動的情況)
推薦閱讀:[Android系統啟動流程 – bootloader]
啟動Linux核心(kernel)
核心啟動時,設定快取、被保護儲存器、計劃列表,載入驅動等系統內部初始化工作。然後核心會尋找並執行”init”檔案,建立init程序作為系統的第一個程序。推薦閱讀:[Android系統啟動流程 – linux kernel]
Android啟動
init程序是Linux核心啟動之後啟動的第一個使用者級程序,Android的啟動也是在這個程序的基礎上開始的,程序號為1。如果是正常啟動init會讀取並解析init.rc檔案,對於init.rc檔案,Android中有特定的格式以及規則。在Android中,叫做Android初始化語言。讀取解析檔案的時,是以行為最小可執行單位解析。解析之後並不會馬上執行,而是在init進入服務迴圈之前統一根據其命令本身所帶的條件來執行。
推薦閱讀:[Android的init過程詳解 ]
二,啟動系統服務
啟動守護程序
init程序會讀取init.rc中的service並按照順序啟動它們,它們是Android的守護程序,比如:
log守護程序(log Daemon):
service logd /system/bin/logd
class core
socket logd stream 0666 logd logd
socket logdr seqpacket 0666 logd logd
socket logdw dgram 0222 logd logd
seclabel u:r:logd:s0
adb守護程序:
service adbd /sbin/adbd --root_seclabel=u:r:su:s0
class core
socket adbd stream 660 system system
disabled
seclabel u:r:adbd:s0
servicemanager:
service servicemanager /system/bin/servicemanager
class core
user system
group system
critical
onrestart restart healthd
onrestart restart zygote
onrestart restart media
onrestart restart surfaceflinger
onrestart restart drm
Network守護程序:
service netd /system/bin/netd
class main
socket netd stream 0660 root system
socket dnsproxyd stream 0660 root inet
socket mdns stream 0660 root system
socket fwmarkd stream 0660 root inet
surfaceflinger:
service surfaceflinger /system/bin/surfaceflinger
class core
user system
group graphics drmrpc
onrestart restart zygote
media:
service media /system/bin/mediaserver
class main
user media
group audio camera inet net_bt net_bt_admin net_bw_acct drmrpc mediadrm qcom_diag
ioprio rt 4
開機動畫:
service bootanim /system/bin/bootanimation
class main
user root
group graphics audio
disabled
oneshot
關機動畫:
service shutdownanim /system/bin/shutdownanimation
class main
user root
group graphics audio
disabled
oneshot
安裝程式:
service installd /system/bin/installd
class main
socket installd stream 600 system system
flash恢復:
service flash_recovery /system/bin/install-recovery.sh
class main
seclabel u:r:install_recovery:s0
oneshot
守護程序是最底層的服務,他們的通訊方式是socket。ServiceManager用來管理系統中所有的binder service,不管是本地的c++實現的還是java語言實現的都需要這個程序來統一管理,最主要的管理就是,註冊新增服務,獲取服務。所有的Service使用前都必須先在servicemanager中進行註冊。
當啟動servicemanager時,會啟動 zygote,surfaceflinger等。Zygote這個程序是非常重要的一個程序,註冊Zygote Socket服務端套接字;載入虛擬機器;預載入Android核心類;預載入系統資源:
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote
class main
socket zygote stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart media
onrestart restart netd
onrestart setprop sys.android.reboot 1
啟動系統服務
zygote中會啟動Xzygote和system-server,從SystemServer開始就是啟動系統服務了:
啟動SystemServer:
namespace android {
static void android_server_SystemServer_startSensorService(JNIEnv* /* env */, jobject /* clazz */) {
char propBuf[PROPERTY_VALUE_MAX];
property_get("system_init.startsensorservice", propBuf, "1");
if (strcmp(propBuf, "1") == 0) {
// 啟動感測器服務
SensorService::instantiate();
}
}
/*
* JNI registration.
*/
static const JNINativeMethod gMethods[] = {
/* name, signature, funcPtr */
{ "startSensorService", "()V", (void*) android_server_SystemServer_startSensorService },
};
int register_android_server_SystemServer(JNIEnv* env)
{
return jniRegisterNativeMethods(env, "com/android/server/SystemServer",
gMethods, NELEM(gMethods));
}
}; // namespace android
com/android/server/SystemServer:
/**
* The main entry point from zygote.
*/
public static void main(String[] args) {
new SystemServer().run();
}
private void run() {
try {
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "InitBeforeStartServices");//跟蹤器開始跟蹤
// 如果裝置的時鐘是 1970以前 (在 0以前), 很多API會發生異常,
// 特別是java.io.File#setLastModified,
// 所以我們假冒一個並且希望會很快獲取時間.
if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
Slog.w(TAG, "System clock is before 1970; setting to 1970.");
SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
}
// 如果系統有 "persist.sys.language" 和好友設定, 用"persist.sys.locale"代替它。
// 使用"-Duser.locale"命令記住預設的本地適當的時候 .
// 這個命令在AndroidRuntime 也用在設定系統屬性,
// 但只有系統伺服器和系統apps 唄允許設定他們.
//
// 注意: Most changes made here will need an equivalent change to
// core/jni/AndroidRuntime.cpp
if (!SystemProperties.get("persist.sys.language").isEmpty()) {
final String languageTag = Locale.getDefault().toLanguageTag();
SystemProperties.set("persist.sys.locale", languageTag);
SystemProperties.set("persist.sys.language", "");
SystemProperties.set("persist.sys.country", "");
SystemProperties.set("persist.sys.localevar", "");
}
// Here we go!
Slog.i(TAG, "Entered the Android system server!");
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, SystemClock.uptimeMillis());
// In case the runtime switched since last boot (such as when
// the old runtime was removed in an OTA), set the system
// property so that it is in sync. We can't do this in
// libnativehelper's JniInvocation::Init code where we already
// had to fallback to a different runtime because it is
// running as root and we need to be the system user to set
// the property. http://b/11463182
SystemProperties.set("persist.sys.dalvik.vm.lib.2", VMRuntime.getRuntime().vmLibrary());
// 啟用取樣分析器.
if (SamplingProfilerIntegration.isEnabled()) {
SamplingProfilerIntegration.start();
mProfilerSnapshotTimer = new Timer();
mProfilerSnapshotTimer.schedule(new TimerTask() {
@Override
public void run() {
SamplingProfilerIntegration.writeSnapshot("system_server", null);
}
}, SNAPSHOT_INTERVAL, SNAPSHOT_INTERVAL);
}
// Mmmmmm... more memory!好多記憶體
VMRuntime.getRuntime().clearGrowthLimit();
// 系統服務會一直執行,所以需要他的記憶體也一直有效.
VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
//一些裝置依賴 runtime 指紋生成, 所以在啟動前確保我們已經聲明瞭它.
Build.ensureFingerprintProperty();
//在系統伺服器中,沒有明確指定使用者的訪問環境路徑是一個錯誤.
Environment.setUserRequired(true);
// 確保傳進系統的binder總是以前臺優先權執行.
BinderInternal.disableBackgroundScheduling(true);
// 準備 main looper thread (這個 thread).
android.os.Process.setThreadPriority(
android.os.Process.THREAD_PRIORITY_FOREGROUND);
android.os.Process.setCanSelfBackground(false);
Looper.prepareMainLooper();
// //載入android_servers.so庫.
System.loadLibrary("android_servers");
// 檢查上一次關機是否失敗.
// 可以沒有返回值.
performPendingShutdown();
// 初始化系統context.
createSystemContext();
// 建立 system service manager物件,新增到本地服務中
mSystemServiceManager = new SystemServiceManager(mSystemContext);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);跟蹤器結束跟蹤
}
// 啟動 services.
try {
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartServices");//跟蹤器開始跟蹤
startBootstrapServices();//啟動引導服務
startCoreServices();//啟動核心服務
startOtherServices();//啟動其他服務
} catch (Throwable ex) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting system services", ex);
throw ex;
} finally {
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
// For debug builds, log event loop stalls to dropbox for analysis.
if (StrictMode.conditionallyEnableDebugLogging()) {
Slog.i(TAG, "Enabled StrictMode for system server main thread.");
}
// 一直Loop .
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
從上面可以看出,先是初始化系統context,然後啟動SystemServiceManager,再然後就是啟動BootstrapServices,CoreServices,OtherServices。BootstrapServices是讓系統啟動的並且會相互影響的關鍵服務,第一個就是ActivityManagerService:
/**啟動引導服務
* 啟動相互影響的關鍵服務 that 讓系統開始啟動
* 這些服務有複雜的相互依賴關係,這就是為什麼我們把它們都放在這一個地方
* 除非你的服務也和這些依賴關係有纏繞,它應該是在另一個功能裡的進行初始化.
*/
private void startBootstrapServices() {
// 等待installd to 完成啟動 ,所以它有一次機會去建立關鍵目錄,和相關許可權。比如/data/user
// 我們需要這個來完成之前我們初始化的其他服務。
Installer installer = mSystemServiceManager.startService(Installer.class);//安裝程式,程式安裝器
// 這個由Activity manager 執行.
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);//設定系統服務管理器
mActivityManagerService.setInstaller(installer);//設定安裝程式
// Power manager需要很早啟動,因為其他服務需要他.
// 本地守護程序可以監聽到他被註冊,所以他必須時刻準備著處理傳進的binder。
// (包括能夠驗證這些呼叫的許可權).
mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
// 現在這個power manager 已經啟動了,讓activity manager初始化power management功能.
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "InitPowerManagement");
mActivityManagerService.initPowerManagement();
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
// 管理LEDs 和 display backlight 所以我們需要他 to bring up the display.
mSystemServiceManager.startService(LightsService.class);
// Display manager需要用來提供顯示度量值 在package manager啟動前。
mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
//我們需要預設的display,在我們可以初始化package manager之前.
mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
//如果我們加密了裝置,只執行"core" apps. decrypt:加密
String cryptState = SystemProperties.get("vold.decrypt");
if (ENCRYPTING_STATE.equals(cryptState)) {
Slog.w(TAG, "Detected encryption in progress - only parsing core apps");
mOnlyCore = true;
} else if (ENCRYPTED_STATE.equals(cryptState)) {
Slog.w(TAG, "Device encrypted - only parsing core apps");
mOnlyCore = true;
}
// 啟動package manager.
traceBeginAndSlog("StartPackageManagerService");
mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);//啟動PackageManagerService
mFirstBoot = mPackageManagerService.isFirstBoot();
mPackageManager = mSystemContext.getPackageManager();//獲取PackageManager
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
//使用者服務新增到服務管理器中
traceBeginAndSlog("StartUserManagerService");
ServiceManager.addService(Context.USER_SERVICE, UserManagerService.getInstance());
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
// 初始化用於快取包中資源的快取屬性.
AttributeCache.init(mSystemContext);
// 為系統程序構建應用例項並且啟動.
mActivityManagerService.setSystemProcess();
//感測器服務需要訪問包管理器服務、應用程式ops服務和許可權服務,因此,我們在他們之後啟動它。
startSensorService();
}
接著啟動一些必要的相對獨立的系統服務:
/**
* 啟動一些必要的,沒和bootstrap 過程中的糾纏 ,的服務.
*/
private void startCoreServices() {
// 跟蹤電池電量. 要求LightService.
mSystemServiceManager.startService(BatteryService.class);
//跟蹤應用程式使用統計.
mSystemServiceManager.startService(UsageStatsService.class);
mActivityManagerService.setUsageStatsManager(
LocalServices.getService(UsageStatsManagerInternal.class));
// UsageStatsService有效後更新, 需要在performBootDexOpt之前.
mPackageManagerService.getUsageStatsIfNoPackageUsageInfo();
//跟蹤可更新的WebView 是否處於就緒狀態 並且監視更新安裝
mSystemServiceManager.startService(WebViewUpdateService.class);
}
最後啟動其他所有的服務:
/**啟動其他五花八門還沒有重構和組織的服務
* .
*/
private void startOtherServices() {
final Context context = mSystemContext;
AccountManagerService accountManager = null;
ContentService contentService = null;
VibratorService vibrator = null;
IAlarmManager alarm = null;
IMountService mountService = null;
NetworkManagementService networkManagement = null;
NetworkStatsService networkStats = null;
NetworkPolicyManagerService networkPolicy = null;
ConnectivityService connectivity = null;
NetworkScoreService networkScore = null;
NsdService serviceDiscovery= null;
WindowManagerService wm = null;
UsbService usb = null;
SerialService serial = null;
NetworkTimeUpdateService networkTimeUpdater = null;
CommonTimeManagementService commonTimeMgmtService = null;
InputManagerService inputManager = null;
TelephonyRegistry telephonyRegistry = null;
ConsumerIrService consumerIr = null;
AudioService audioService = null;
MmsServiceBroker mmsService = null;
EntropyMixer entropyMixer = null;
CameraService cameraService = null;
boolean disableStorage = SystemProperties.getBoolean("config.disable_storage", false);
boolean disableBluetooth = SystemProperties.getBoolean("config.disable_bluetooth", false);
boolean disableLocation = SystemProperties.getBoolean("config.disable_location", false);
boolean disableSystemUI = SystemProperties.getBoolean("config.disable_systemui", false);
boolean disableNonCoreServices = SystemProperties.getBoolean("config.disable_noncore", false);
boolean disableNetwork = SystemProperties.getBoolean("config.disable_network", false);
boolean disableNetworkTime = SystemProperties.getBoolean("config.disable_networktime", false);
boolean isEmulator = SystemProperties.get("ro.kernel.qemu").equals("1");
try {
Slog.i(TAG, "Reading configuration...");//列印“讀取配置。。。”
SystemConfig.getInstance();//獲取SystemConfig物件
traceBeginAndSlog("StartSchedulingPolicyService");
ServiceManager.addService("scheduling_policy", new SchedulingPolicyService());//排程策略
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
...略
StatusBarManagerService statusBar = null;//狀態條
INotificationManager notification = null;//通知
InputMethodManagerService imm = null;//輸入工具
WallpaperManagerService wallpaper = null;//桌布
LocationManagerService location = null;//位置
CountryDetectorService countryDetector = null;//國家
TextServicesManagerService tsms = null;//text
LockSettingsService lockSettings = null;//鎖屏設定
AssetAtlasService atlas = null;//資產阿特拉斯
MediaRouterService mediaRouter = null;//媒體路由
// Bring up services needed for UI.
if (mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
traceBeginAndSlog("StartInputMethodManagerService");
try {
imm = new InputMethodManagerService(context, wm);
ServiceManager.addService(Context.INPUT_METHOD_SERVICE, imm);
} catch (Throwable e) {
reportWtf("starting Input Manager Service", e);
}
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
traceBeginAndSlog("StartAccessibilityManagerService");
try {
ServiceManager.addService(Context.ACCESSIBILITY_SERVICE,
new AccessibilityManagerService(context));
} catch (Throwable e) {
reportWtf("starting Accessibility Manager", e);
}
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
try {
wm.displayReady();
} catch (Throwable e) {
reportWtf("making display ready", e);
}
...略
// These are needed to propagate to the runnable below.
final NetworkManagementService networkManagementF = networkManagement;
final NetworkStatsService networkStatsF = networkStats;
final NetworkPolicyManagerService networkPolicyF = networkPolicy;
final ConnectivityService connectivityF = connectivity;
final NetworkScoreService networkScoreF = networkScore;
final WallpaperManagerService wallpaperF = wallpaper;
final InputMethodManagerService immF = imm;
final LocationManagerService locationF = location;
final CountryDetectorService countryDetectorF = countryDetector;
final NetworkTimeUpdateService networkTimeUpdaterF = networkTimeUpdater;
final CommonTimeManagementService commonTimeMgmtServiceF = commonTimeMgmtService;
final TextServicesManagerService textServiceManagerServiceF = tsms;
final StatusBarManagerService statusBarF = statusBar;
final AssetAtlasService atlasF = atlas;
final InputManagerService inputManagerF = inputManager;
final TelephonyRegistry telephonyRegistryF = telephonyRegistry;
final MediaRouterService mediaRouterF = mediaRouter;
final AudioService audioServiceF = audioService;
final MmsServiceBroker mmsServiceF = mmsService;
// We now tell the activity manager it is okay to run third party
// code. It will call back into us once it has gotten to the state
// where third party code can really run (but before it has actually
// started launching the initial applications), for us to complete our
// initialization.
mActivityManagerService.systemReady(new Runnable() {
@Override
public void run() {
Slog.i(TAG, "Making services ready");
mSystemServiceManager.startBootPhase(
SystemService.PHASE_ACTIVITY_MANAGER_READY);
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "PhaseActivityManagerReady");
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartObservingNativeCrashes");
try {
mActivityManagerService.startObservingNativeCrashes();
} catch (Throwable e) {
reportWtf("observing native crashes", e);
}
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
Slog.i(TAG, "WebViewFactory preparation");
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "WebViewFactoryPreparation");
WebViewFactory.prepareWebViewInSystemServer();
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartSystemUI");
try {
startSystemUi(context);
} catch (Throwable e) {
reportWtf("starting System UI", e);
}
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "MakeMountServiceReady");
try {
if (networkScoreF != null) networkScoreF.systemReady();
} catch (Throwable e) {
reportWtf("making Network Score Service ready", e);
}
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
。。。略
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
});
}
//啟動系統UI
static final void startSystemUi(Context context) {
Intent intent = new Intent();
intent.setComponent(new ComponentName("com.android.systemui",
"com.android.systemui.SystemUIService"));
//Slog.d(TAG, "Starting service: " + intent);
context.startServiceAsUser(intent, UserHandle.OWNER);
}
在不同的程序中執行的系統服務之間的通訊方式為Binder。
系統服務啟動的方式
觀察上面的啟動服務的程式碼,最普遍的有三種方式啟動系統服務,比如:
//通過SystemServiceManager.startService進行啟動:
mSystemServiceManager.startService(TelecomLoaderService.class);//傳入類名
private static final String WIFI_SERVICE_CLASS =
"com.android.server.wifi.WifiService";
mSystemServiceManager.startService(WIFI_SERVICE_CLASS);//傳入字串
//通過ServiceManager.addService啟動:
networkManagement = NetworkManagementService.create(context);
ServiceManager.addService(Context.NETWORKMANAGEMENT_SERVICE, networkManagement);//傳入Context中定義的變數名,服務
vibrator = new VibratorService(context);
ServiceManager.addService("vibrator", vibrator);//傳入字串,服務
//其他:
if (audioServiceF != null) audioServiceF.systemReady();
if (networkTimeUpdaterF != null) networkTimeUpdaterF.systemRunning();
SystemServiceManager.startService()
SystemServiceManager是一個管理com.android.server.SystemService 系統服務建立,啟動,和一些生命週期事件的類。
先看SystemServiceManager.startService方法,此方法名有兩個個方法體,一個出入引數為字串,一個傳入引數為Class類名,方法分別如下:
/**
* 通過類名啟動一個服務.
*
* @return 服務物件.
*/
@SuppressWarnings("unchecked")
public SystemService startService(String className) {
final Class<SystemService> serviceClass;//SystemService子類
try {
serviceClass = (Class<SystemService>)Class.forName(className);//返回的是一個類,作用是要求JVM查詢並載入指定的類
} catch (ClassNotFoundException ex) {
Slog.i(TAG, "Starting " + className);
throw new RuntimeException("Failed to create service " + className
+ ": service class not found, usually indicates that the caller should "
+ "have called PackageManager.hasSystemFeature() to check whether the "
+ "feature is available on this device before trying to start the "
+ "services that implement it", ex);
}
return startService(serviceClass);//再執行下面的startService方法,並返回值
}
// Services that 應該接受生命週期事件.
private final ArrayList<SystemService> mServices = new ArrayList<SystemService>();
/**
* 建立和啟動一個系統服務.
* 這個類必須是{@link com.android.server.SystemService}的子類.
*
* @param serviceClass 實現SystemService介面的java類.
* @return 返回服務物件,不可以為null.
* @throws RuntimeException 啟動失敗丟擲異常.
*/
@SuppressWarnings("unchecked")
public <T extends SystemService> T startService(Class<T> serviceClass) {
try {
final String name = serviceClass.getName();//獲得類的名字
Slog.i(TAG, "Starting " + name);
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartService " + name);
// 建立service物件.
//isAssignableFrom是用來判斷一個類Class1和另一個類Class2是否相同或是另一個類的超類或介面
if (!SystemService.class.isAssignableFrom(serviceClass)) {
throw new RuntimeException("Failed to create " + name
+ ": service must extend " + SystemService.class.getName());//服務必須extendSystemService
}
final T service;
try {
Constructor<T> constructor = serviceClass.getConstructor(Context.class);//獲取服務的構造器
service = constructor.newInstance(mContext);//建立服務的物件
} catch (InstantiationException ex) {
throw new RuntimeException("Failed to create service " + name
+ ": service could not be instantiated", ex);//服務不能被例項化,丟擲異常
} catch (IllegalAccessException ex) {
throw new RuntimeException("Failed to create service " + name
+ ": service must have a public constructor with a Context argument", ex);
} catch (NoSuchMethodException ex) {
throw new RuntimeException("Failed to create service " + name
+ ": service must have a public constructor with a Context argument", ex);
} catch (InvocationTargetException ex) {
throw new RuntimeException("Failed to create service " + name
+ ": service constructor threw an exception", ex);
}
// Register it.
mServices.add(service);//註冊服務,新增到ArrayList<SystemService> mServices中
// 啟動服務.
try {
service.onStart();
} catch (RuntimeException ex) {
throw new RuntimeException("Failed to start service " + name
+ ": onStart threw an exception", ex);
}
return service;//返回服務
} finally {
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
}
可以看出這兩個方法執行的系統服務類都是SystemService的子類。在第二個方法中,先是判斷這個服務是不是SystemService的子類,,然後我們建立服務的物件,再通過新增到服務列表新增到ArrayList mServices中,並且同時通過呼叫SystemService.onStart()方法對這個啟動的服務進行相關配置。onStart()方法由SystemService的子類實現,就是啟動哪個服務就呼叫哪個服務類裡的onStart()方法,比如BatteryService服務類:
@Override
public void onStart() {
IBinder b = ServiceManager.getService("batteryproperties");//獲取屬性配置
final IBatteryPropertiesRegistrar batteryPropertiesRegistrar =
IBatteryPropertiesRegistrar.Stub.asInterface(b);
try {
batteryPropertiesRegistrar.registerListener(new BatteryListener());//註冊電量監聽
} catch (RemoteException e) {
// Should never happen.
}
publishBinderService("battery", new BinderService());
publishLocalService(BatteryManagerInternal.class, new LocalService());
}
然而我們此時可以發現SystemServiceManager.startService方法只是載入了系統服務,並沒有啟動,仔細閱讀SystemServer類我們會發現,程式碼每執行一段後會執行如下方法:
mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
startBootPhase方法作用是啟動執行到這兒的這一階段的所有系統服務,引數為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;
/**
*到了這兒,服務可以接受廣播Intents.
*/
public static final int PHASE_ACTIVITY_MANAGER_READY = 550;
/**
* 到了這兒,服務可以啟動/繫結第三方apps.
*/
public static final int PHASE_THIRD_PARTY_APPS_CAN_START = 600;
/**
* 當收到這個啟動指令, 服務允許使用者與裝置互動.裝置開機完成並且啟動了桌面應用
*/
public static final int PHASE_BOOT_COMPLETED = 1000;
SystemServiceManager.startBootPhase方法為:
/**啟動執行到這兒的這一階段的所有系統服務
* @param phase The boot phase to start.
*/
public void startBootPhase(final int phase) {
if (phase <= mCurrentPhase) {//是否小於當前的階段常量值
throw new IllegalArgumentException("Next phase must be larger than previous");
}
mCurrentPhase = phase;
Slog.i(TAG, "Starting phase " + mCurrentPhase);
try {
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "OnBootPhase " + phase);
final int serviceLen = mServices.size();//獲取mServices的大小
for (int i = 0; i < serviceLen; i++) {
final SystemService service = mServices.get(i);//獲取服務
try {
service.onBootPhase(mCurrentPhase);//呼叫SystemService.onBootPhase()方法啟動
} catch (Exception ex) {
throw new RuntimeException("Failed to boot service "
+ service.getClass().getName()
+ ": onBootPhase threw an exception during phase "
+ mCurrentPhase, ex);//啟動失敗丟擲異常,在mCurrentPhase階段
}
}
} finally {
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
}
這裡又呼叫了SystemService.onBootPhase()方法的實現方法,比如啟動到了BatteryService服務,BatteryService.onBootPhase():
@Override
public void onBootPhase(int phase) {
if (phase == PHASE_ACTIVITY_MANAGER_READY) {
// check our power situation now that it is safe to display the shutdown dialog.
synchronized (mLock) {
ContentObserver obs = new ContentObserver(mHandler) {
@Override
public void onChange(boolean selfChange) {
synchronized (mLock) {
updateBatteryWarningLevelLocked();
}
}
};
final ContentResolver resolver = mContext.getContentResolver();
resolver.registerContentObserver(Settings.Global.getUriFor(
Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL),
false, obs, UserHandle.USER_ALL);
updateBatteryWarningLevelLocked();
}
}
}
ServiceManager.addService()
/**
* 放進service manager 中@a service called @a name .
*
* @param name 新service的名字
* @param service service物件
*/
public static void addService(String name, IBinder service) {
try {
getIServiceManager().addService(name, service, false);
} catch (RemoteException e) {
Log.e(TAG, "error in addService", e);
}
}
getIServiceManager()如下,返回的是一個IServiceManager物件:
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
// 查詢service manager
sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
return sServiceManager;
}
查詢service manager中呼叫了ServiceManagerNative.asInterface():
/**
* 將一個Binder物件轉換成一個 service manager介面;生成一個代理,如果需要.
*/
static public IServiceManager asInterface(IBinder obj)
{
if (obj == null) {
return null;
}
//查詢本地是否有IServiceManager
IServiceManager in =
(IServiceManager)obj.queryLocalInterface(descriptor);//queryLocalInterface(descriptor)返回值是IInterface型別,其是IServiceManager的父介面
if (in != null) {
return in;
}
return new ServiceManagerProxy(obj);//如果沒有則返回ServiceManagerProxy物件
}
此時可得getIServiceManager().addService()就是ServiceManagerProxy.addService():
public void addService(String name, IBinder service, boolean allowIsolated)
throws RemoteException {
/準備Parcel資料
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IServiceManager.descriptor);
data.writeString(name);
data.writeStrongBinder(service);
data.writeInt(allowIsolated ? 1 : 0);
//獲取結果
mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
//回收物件的引用
reply.recycle();
data.recycle();
}
ServiceManager相關類關係圖:
如果簡單來說,這裡一部分類之間使用了代理模式:
代理模式
代理模式:為其它物件提供一種代理以控制對這個物件的訪問。
1,抽象介面IServiceManager:它聲明瞭真實主題和代理主題的共同介面,這樣一來在任何使用真實主題的地方都可以使用代理主題,客戶端通常需要針對抽象主題角色進行程式設計。
2,代理類ServiceManagerNative:它包含了對真實類的引用,從而可以在任何時候操作真實類物件;在代理類中提供一個可以使用的介面,以便在任何時候都可以替代真實類,供客戶端使用;代理類還可以控制對真實類的使用,負責在需要的時候建立和刪除真實類物件,並對真實類物件的使用加以約束。通常,在代理類中,客戶端在呼叫所引用的真實類操作之前或之後還需要執行其他操作,而不僅僅是單純呼叫真實類物件中的操作。
對真實類的引用,控制對真實類的訪問:如果本地已經快取有了,使用本地的,否則呼叫真實類ServiceManagerProxy的物件:
/**
* 將一個Binder物件轉換成一個 service manager介面;.
*/
static public IServiceManager asInterface(IBinder obj)
{
if (obj == null) {
return null;
}
IServiceManager in =
(IServiceManager)obj.queryLocalInterface(descriptor);//查詢本地是否有IServiceManager
if (in != null) {
return in;
}
return new ServiceManagerProxy(obj);//如果沒有則