Android SystemServiceManager分析
1. SystemServiceManger啟動
分析過SystemServer的朋友應該都有記憶,SystemServiceManager就是在SystemServer中啟動的,下面是SystemServiceManager的啟動代碼:
[SystemServer.java] // Create the system service manager. mSystemServiceManager = new SystemServiceManager(mSystemContext); LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);這里直接通過new一個SystemServiceManager對象,然后將新new的對象保存到mSystemServiceManager中,以備后用。
??SystemServiceManager的代碼如下:
public SystemServiceManager(Context context) {mContext = context; }這里只要將context保存到mContext中即可,現在SystemServiceManager就初始化完畢了。
2. SystemServiceManager代碼分析
2.1 SystemServiceManager中的startService函數
/*** Starts a service by class name.** @return The service instance.*/ @SuppressWarnings("unchecked") public SystemService startService(String className) {// SystemrService類的class對象final Class<SystemService> serviceClass;try {// 通過Class.forName,傳入String型類名,得到對應類名的class對象serviceClass = (Class<SystemService>)Class.forName(className);} 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);}// 調用另一個startService重載函數return startService(serviceClass); }/*** Creates and starts a system service. The class must be a subclass of* {@link com.android.server.SystemService}.** @param serviceClass A Java class that implements the SystemService interface.* @return The service instance, never null.* @throws RuntimeException if the service fails to start.*/ @SuppressWarnings("unchecked") // 模板類函數,其中serviceClass必須是SystemService的子類 public <T extends SystemService> T startService(Class<T> serviceClass) {final String name = serviceClass.getName();Slog.i(TAG, "Starting " + name);// Create the service.// 再次確認serviceClass是SystemService的子類if (!SystemService.class.isAssignableFrom(serviceClass)) {throw new RuntimeException("Failed to create " + name+ ": service must extend " + SystemService.class.getName());}final T service;try {// 獲取service的構造函數Constructor<T> constructor = serviceClass.getConstructor(Context.class);// 創建service對象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.// 將service添加到mServices ArrayList中mServices.add(service);// Start it.try {// 啟動serviceservice.onStart();} catch (RuntimeException ex) {throw new RuntimeException("Failed to start service " + name+ ": onStart threw an exception", ex);}return service; }2.2 SystemServiceManager中的startBootPhase函數
/*** Starts the specified boot phase for all system services that have been started up to* this point.** @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);// 輪詢mServices中所有的servicefinal int serviceLen = mServices.size();for (int i = 0; i < serviceLen; i++) {final SystemService service = mServices.get(i);try {/// M: Service operation time log @{long startTime = 0;if (!IS_USER_BUILD) startTime = SystemClock.elapsedRealtime();/// @}// 調用service的onBootPhase方法service.onBootPhase(mCurrentPhase);/// M: Service operation time log @{if (!IS_USER_BUILD) {checkTime(startTime, "Phase " + mCurrentPhase, service.getClass().getName());}/// @}} catch (Exception ex) {throw new RuntimeException("Failed to boot service "+ service.getClass().getName()+ ": onBootPhase threw an exception during phase "+ mCurrentPhase, ex);}} }??startBootPhase也比較簡單,因為有些service的啟動需要以來其他的service,所以Systemserver會將設備啟動分成幾個階段,每個階段啟動不同的service,而這些就是由startBootPhase這個方法來實現的。如果檢測到當前的phase達到service的設定值,service就會完成相應的工作。下面是BatteryService的onBootPhase方法,可以知道當設備啟動到PHASE_ACTIVITY_MANAGER_READY,該方法就會調用執行相應的操作。
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) {mBootCompleted = true;ContentObserver obs = new ContentObserver(mHandler) {@Overridepublic 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();}} }2.3 SystemServiceManager中剩余關于user的函數
??SystemServiceManager中剩余一下關于特定user的函數,具體的使用場景在SystemService.java中有描述,大家可以看下面代碼中的注釋,簡單明了。
/*** Called when switching to a different foreground user, for system services that have* special behavior for whichever user is currently in the foreground. This is called* before any application processes are aware of the new user.* @param userHandle The identifier of the user.*/ public void onSwitchUser(int userHandle) {}/*** Called when an existing user is stopping, for system services to finalize any per-user* state they maintain for running users. This is called prior to sending the SHUTDOWN* broadcast to the user; it is a good place to stop making use of any resources of that* user (such as binding to a service running in the user).* @param userHandle The identifier of the user.*/ public void onStopUser(int userHandle) {}/*** Called when an existing user is stopping, for system services to finalize any per-user* state they maintain for running users. This is called after all application process* teardown of the user is complete.* @param userHandle The identifier of the user.*/ public void onCleanupUser(int userHandle) {}3. 看看SystemService的內容
??系統中存在部分service是systemservice的子類,所以就順便看看Systemservice的代碼都有哪些:
public abstract class SystemService {// 列出設備啟動的各個階段/** Boot Phases*/public static final int PHASE_WAIT_FOR_DEFAULT_DISPLAY = 100; // maybe should be a dependency?/*** After receiving this boot phase, services can obtain lock settings data.*/public static final int PHASE_LOCK_SETTINGS_READY = 480;/*** After receiving this boot phase, services can safely call into core system services* such as the PowerManager or PackageManager.*/public static final int PHASE_SYSTEM_SERVICES_READY = 500;/*** After receiving this boot phase, services can broadcast Intents.*/public static final int PHASE_ACTIVITY_MANAGER_READY = 550;/*** After receiving this boot phase, services can start/bind to third party apps.* Apps will be able to make Binder calls into services at this point.*/public static final int PHASE_THIRD_PARTY_APPS_CAN_START = 600;/*** After receiving this boot phase, services can allow user interaction with the device.* This phase occurs when boot has completed and the home application has started.* System services may prefer to listen to this phase rather than registering a* broadcast receiver for ACTION_BOOT_COMPLETED to reduce overall latency.*/public static final int PHASE_BOOT_COMPLETED = 1000;private final Context mContext;/*** Initializes the system service.* * Subclasses must define a single argument constructor that accepts the context* and passes it to super.* ** @param context The system server context.*/// systemservice的構造函數public SystemService(Context context) {mContext = context;}/*** Gets the system context.*/public final Context getContext() {return mContext;}/*** Returns true if the system is running in safe mode.* TODO: we should define in which phase this becomes valid*/public final boolean isSafeMode() {return getManager().isSafeMode();}/*** Called when the dependencies listed in the @Service class-annotation are available* and after the chosen start phase.* When this method returns, the service should be published.*/public abstract void onStart();/*** Called on each phase of the boot process. Phases before the service's start phase* (as defined in the @Service annotation) are never received.** @param phase The current boot phase.*/public void onBootPhase(int phase) {}/*** Called when a new user is starting, for system services to initialize any per-user* state they maintain for running users.* @param userHandle The identifier of the user.*/public void onStartUser(int userHandle) {}/*** Called when switching to a different foreground user, for system services that have* special behavior for whichever user is currently in the foreground. This is called* before any application processes are aware of the new user.* @param userHandle The identifier of the user.*/public void onSwitchUser(int userHandle) {}/*** Called when an existing user is stopping, for system services to finalize any per-user* state they maintain for running users. This is called prior to sending the SHUTDOWN* broadcast to the user; it is a good place to stop making use of any resources of that* user (such as binding to a service running in the user).* @param userHandle The identifier of the user.*/public void onStopUser(int userHandle) {}/*** Called when an existing user is stopping, for system services to finalize any per-user* state they maintain for running users. This is called after all application process* teardown of the user is complete.* @param userHandle The identifier of the user.*/public void onCleanupUser(int userHandle) {}/*** Publish the service so it is accessible to other services and apps.*/protected final void publishBinderService(String name, IBinder service) {publishBinderService(name, service, false);}/*** Publish the service so it is accessible to other services and apps.*/protected final void publishBinderService(String name, IBinder service,boolean allowIsolated) {ServiceManager.addService(name, service, allowIsolated);}/*** Get a binder service by its name.*/protected final IBinder getBinderService(String name) {return ServiceManager.getService(name);}/*** Publish the service so it is only accessible to the system process.*/protected final void publishLocalService(Class type, T service) {LocalServices.addService(type, service);}/*** Get a local service by interface.*/protected final T getLocalService(Class type) {return LocalServices.getService(type);}private SystemServiceManager getManager() {return LocalServices.getService(SystemServiceManager.class);} }??其中比較感興趣的是publishBinderService這個方法,在之前看到這個函數還不知道是做什么用的,現在看到這個方法的代碼,瞬間清晰了,這個方法最終也還是會調用ServiceManager.addService方法,將service添加到ServiceManager中。
??另一個感興趣的方法是publishLocalService,這個方法將一些要在system process中用到的service添加到LocalServices static類對象中,這個類內部通過ArrayMap將這些service記錄起來,到后面需要使用就可以非??焖俜奖愕娜〕鰜砹?。
http://blog4jimmy.com/2018/01/330.html
總結
以上是生活随笔為你收集整理的Android SystemServiceManager分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android SystemServer
- 下一篇: Android工程模块化平台的设计