從 Android 應用的角度來講,系統啓動以後,會在一個名爲 system_server
的進程中啓動一系列的 Services,以向每一個進程應用(Application Process)提供各式各樣的「服務」,每一個 Service 各思其職。好比,你們最熟悉的 Activity 以及其餘組件,其生命週期則是由 ActivityManagerService
這個服務來管理的。java
而對於開發者而言,在一個普通應用的開發過程當中,和系統機制有關的功能都是由這些系統服務來提供實現的。換句話說,咱們大部分時候所實現的功能本質上都是在和這些系統服務「打交道」。爲了方便開發者使用,Android SDK 內對每一個系統 Service 都作了必定程度的封裝,提供了必要的 API 來調用。android
好比,開發中經常使用到,設置一個定時鬧鐘任務:web
PendingIntent pi = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager alarmManager = (AlarmManager) getSystemService(Service.ALARM_SERVICE); alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 5 * 1000, pi); 複製代碼
在這裏,當前應用進程是經過 AlarmManager
來實現設置定時鬧鐘,其背後是調用了 AlarmManagerService
來實現相關操做。緩存
系統 Services 從建立到使用的總體流程示意以下:架構
其中,整個流程,可分爲如下四個步驟(分別對應上圖中的數字處):app
一、系統 Service 在 system_server
進程中建立、啓動;編輯器
二、系統 Service 發佈 Binder Service 至 Native Framework 的 ServiceManager
中;ide
三、在應用啓動的過程當中,ActivityManagerService
從 ServiceManager
(native)中獲取其餘經常使用的服務(BinderProxy
對象),傳遞到應用進程的 ServiceManager
(java) 中;學習
四、應用進程中建立各個使用服務的 Manager 對象,如 WindowManager
等,經過上下文 Context
調用使用。fetch
下面的部分會經過源碼示例的方式,把以上四個步驟具體流程、實現方式深刻分析一下,讀者可根據本身想要了解的部分自行跳轉閱讀,目錄在右側 👉 可找到 。
frameworks/base/services/java/com/android/sever/ - SystemServer.java - SystemServiceManager.java - AlarmManagerService.java - am/ActivityManagerService.java frameworks/base/core/java/android/os/ - ServiceManager.java - ServiceManagerNative.java frameworks/base/core/java/android/app/ - ActivityThread.java - ContextImpl.java - SystemServiceRegistry.java frameworks/native/libs/binder/ - IServiceManager.cpp frameworks/native/cmds/servicemanager/ - ServiceManager.h - ServiceManager.cpp 複製代碼
注:源碼部分用的 Android 10(Q)版本的,不一樣的 Android 系統版本在實現的方式存在必定的差別,但總體流程是同樣的。
system_server
進程建立後,在SystemServer
中的 main 方法爲入口,依次啓動各 Services。
···
// SystemServer 進程主方法入口 public static void main(String[] args) { new SystemServer().run(); } private void run() { ··· // 建立 SystemServiceManager,用於後續管理系統 Services mSystemServiceManager = new SystemServiceManager(mSystemContext); mSystemServiceManager.setStartInfo(mRuntimeRestart, mRuntimeStartElapsedTime, mRuntimeStartUptime); LocalServices.addService(SystemServiceManager.class, mSystemServiceManager); ··· // Start services. startBootstrapServices(); // 啓動系統電池、GPU 等核心服務 startCoreServices(); // 大部分應用直接所需的服務在此啓動 startOtherServices(); ··· } private void startOtherServices() { ··· // 啓動 AlarmManagerService mSystemServiceManager.startService(new AlarmManagerService(context)); ··· // 啓動 ActivityManagerService mActivityManagerService = ActivityManagerService.Lifecycle.startService( mSystemServiceManager, atm); // 啓動其餘的 Services ··· } ··· 複製代碼
其中,不一樣的 Service 的建立過程會有必定的差別,有的是直接 new 出一個對象,有的經過反射的形式建立,有得須要註冊回調等,但核心的流程是同樣的。
在 Service 對象建立以後,回調其父類 SystemService
onStart 方法,這樣一個 Service 就算啓動了。
···
private final ArrayList<SystemService> mServices = new ArrayList<SystemService>(); // 啓動系統服務 public void startService(@NonNull final SystemService service) { // 添加 service 對象到一個 List 中 mServices.add(service); ··· // 回調 onStart try { service.onStart(); } ··· } 複製代碼
到此,一個系統 Service 尚未真正的完成註冊。全部的 Services 對象是建立在 system_server
進程的,而後經過 Binder 與每個應用進程進行跨進程通訊(IPC),所以須要發佈一個 Binder Service,以 AlarmManagerService
爲例:
class AlarmManagerService extends SystemService {
··· // 建立一個 IBinder Service 對象,用於實現 Binder 通訊 private final IBinder mService = new IAlarmManager.Stub() { // 設置定時鬧鐘的接口實現 @Override public void set(String callingPackage, int type, long triggerAtTime, ...) { ··· setImpl(type, triggerAtTime, ...); } ··· } // 設置定時鬧鐘真正方法入口 void setImpl(int type, long triggerAtTime, ...) { ... } @Override public void onStart() { ··· // onStart 回調中發佈該 Binder Service publishBinderService(Context.ALARM_SERVICE, mService); } // 經過 ServiceManager 添加 Binder Service protected final void publishBinderService(String name, IBinder service, boolean allowIsolated, int dumpPriority) { ServiceManager.addService(name, service, allowIsolated, dumpPriority); } ··· } 複製代碼
ServiceManager
主要用於 Service 的添加與獲取。
···
public static void addService(String name, IBinder service, boolean allowIsolated, int dumpPriority) { try { // 添加一個 Service,這裏一樣是 IPC 通訊 getIServiceManager().addService(name, service, allowIsolated, dumpPriority); } catch (RemoteException e) { Log.e(TAG, "error in addService", e); } } private static IServiceManager getIServiceManager() { if (sServiceManager != null) { return sServiceManager; } // 找到 ServiceManager 對象 // BinderInternal.getContextObject() 爲 native 方法, // 返回指向 IServiceManager 的 BinderProxy 對象 sServiceManager = ServiceManagerNative .asInterface(Binder.allowBlocking(BinderInternal.getContextObject())); return sServiceManager; } ··· 複製代碼
接着,往下看 ServiceManagerNative
:
public final class ServiceManagerNative {
··· public static IServiceManager asInterface(IBinder obj) { if (obj == null) { return null; } // ServiceManager 的代理對象 return new ServiceManagerProxy(obj); } // 這裏等同於 IServiceManager$Stub$Proxy class ServiceManagerProxy implements IServiceManager { public ServiceManagerProxy(IBinder remote) { mRemote = remote; mServiceManager = IServiceManager.Stub.asInterface(remote); } // 獲取服務 public IBinder getService(String name) throws RemoteException { return mServiceManager.checkService(name); } // 添加服務 public void addService(String name, IBinder service, boolean allowIsolated, int dumpPriority) throws RemoteException { mServiceManager.addService(name, service, allowIsolated, dumpPriority); } } } 複製代碼
從這裏能夠看到,發佈一個 Service 的過程自己也是 Binder IPC 的方式實現的,最終會傳遞到 servicemanager
進程中,在 IServiceManager.cpp 內:
class BpServiceManager : public BpInterface<IServiceManager>
{ public: explicit BpServiceManager(const sp<IBinder>& impl) : BpInterface<IServiceManager>(impl), mTheRealServiceManager(interface_cast<AidlServiceManager>(impl)) { } // 添加 Service 到 ServiceManager status_t addService(const String16& name, const sp<IBinder>& service, bool allowIsolated, int dumpsysPriority) override { Status status = mTheRealServiceManager->addService(String8(name).c_str(), service, allowIsolated, dumpsysPriority); return status.exceptionCode(); } ... } 複製代碼
這裏,Native Framework 中的 ServiceManager
是整個 Binder IPC 架構的服務中心,全部大大小小的 service 都須要通過 ServiceManager
來管理
···
private: // 定義 Service 的結構體 struct Service { sp<IBinder> binder; // not null bool allowIsolated; int32_t dumpPriority; }; ··· using ServiceMap = std::map<std::string, Service>; // 用於保存添加進來的 Services ServiceMap mNameToService; ··· }; 複製代碼
Status ServiceManager::addService(const std::string& name, const sp<IBinder>& binder, bool allowIsolated, int32_t dumpPriority) {
··· // 添加 Service 到 mNameToService 中,完成 Binder Service 註冊過程 mNameToService[name] = Service { .binder = binder, .allowIsolated = allowIsolated, .dumpPriority = dumpPriority, }; auto it = mNameToCallback.find(name); if (it != mNameToCallback.end()) { for (const sp<IServiceCallback>& cb : it->second) { // permission checked in registerForNotifications cb->onRegistration(name, binder); } } return Status::ok(); } 複製代碼
在新啓動一個應用的過程當中,建立應用進程以後,ActivityManagerService
中會獲取並緩存經常使用的系統 Services,經過回調 IApplicationThread.bindApplication() 方法傳遞 Service 的 BinderProxy 對象到應用進程中去。
// IActivityManager 的 server 端實現
@Override public final void attachApplication(IApplicationThread thread, long startSeq) { synchronized (this) { int callingPid = Binder.getCallingPid(); final int callingUid = Binder.getCallingUid(); final long origId = Binder.clearCallingIdentity(); // 這裏 thread 實際爲 IApplicationThread$Stub$Proxy 對象, attachApplicationLocked(thread, callingPid, callingUid, startSeq); Binder.restoreCallingIdentity(origId); } } @GuardedBy("this") private final boolean attachApplicationLocked(IApplicationThread thread, int pid, int callingUid, long startSeq) { ··· thread.bindApplication(processName, appInfo, providers, ··· getCommonServicesLocked(app.isolated), // 獲取各經常使用服務 ···); ··· return true; } private ArrayMap<String, IBinder> getCommonServicesLocked(boolean isolated) { ··· if (mAppBindArgs == null) { mAppBindArgs = new ArrayMap<>(); // 添加經常使用的服務進一個 map 中 addServiceToMap(mAppBindArgs, "package"); addServiceToMap(mAppBindArgs, Context.WINDOW_SERVICE); addServiceToMap(mAppBindArgs, Context.ALARM_SERVICE); addServiceToMap(mAppBindArgs, Context.DISPLAY_SERVICE); ··· } return mAppBindArgs; } private static void addServiceToMap(ArrayMap<String, IBinder> map, String name) { // 經過 ServiceManager 獲取服務 final IBinder service = ServiceManager.getService(name); if (service != null) { map.put(name, service); if (false) { Log.i(TAG, "Adding " + name + " to the pre-loaded service cache."); } } } 複製代碼
經過 ServiceManager
來獲取 Service 的過程和添加一個 Service 的流程是同樣的,最終從 Native Framework 中的 ServiceManager
獲取到該服務的 BinderProxy 對象。
IApplicationThread
的 server 端實如今 ActivityThread
中:
public final class ActivityThread extends ClientTransactionHandler {
··· private class ApplicationThread extends IApplicationThread.Stub { // 傳遞指向系統 Service 的 BinderProxy 對象 public final void bindApplication(···, Map services, ···) { if (services != null) { ··· // 添加進應用進程的 ServiceManager 中 ServiceManager.initServiceCache(services); } } } } 複製代碼
public static void initServiceCache(Map<String, IBinder> cache) {
if (sCache.size() != 0) { throw new IllegalStateException("setServiceCache may only be called once"); } // 存進 cache sCache.putAll(cache); } 複製代碼
Context
上下文提供了 getSystemService 接口調用,Context
的真正實現類是 ContextImpl
:
···
@Override public Object getSystemService(String name) { return SystemServiceRegistry.getSystemService(this, name); } 複製代碼
SystemServiceRegistry
負責根據 ServiceManager
中各 Service 的 BinderProxy
來建立 Binder 通訊的 client 端對象,並封裝在對應的 Manager 對象。
// 管理{@link ContextImpl#getSystemService} 能夠返回的全部系統服務
final class SystemServiceRegistry { ··· private static final Map<Class<?>, String> SYSTEM_SERVICE_NAMES = new ArrayMap<Class<?>, String>(); private static final Map<String, ServiceFetcher<?>> SYSTEM_SERVICE_FETCHERS = new ArrayMap<String, ServiceFetcher<?>>(); ··· // SystemServiceRegistry 類被加載時建立各 Manager 對象 static { registerService(Context.ALARM_SERVICE, AlarmManager.class, new CachedServiceFetcher<AlarmManager>() { @Override public AlarmManager createService(ContextImpl ctx) throws ServiceNotFoundException { IBinder b = ServiceManager.getServiceOrThrow(Context.ALARM_SERVICE); IAlarmManager service = IAlarmManager.Stub.asInterface(b); return new AlarmManager(service, ctx); }}); ··· registerService(Context.ACTIVITY_SERVICE, ActivityManager.class, new CachedServiceFetcher<ActivityManager>() { @Override public ActivityManager createService(ContextImpl ctx) { return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler()); }}); ··· } private static <T> void registerService(String serviceName, Class<T> serviceClass, ServiceFetcher<T> serviceFetcher) { SYSTEM_SERVICE_NAMES.put(serviceClass, serviceName); SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher); } // 返回系統 Service 對應的 Manager 對象 public static Object getSystemService(ContextImpl ctx, String name) { ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name); return fetcher != null ? fetcher.getService(ctx) : null; } } 複製代碼
public static IBinder getServiceOrThrow(String name) throws ServiceNotFoundException {
final IBinder binder = getService(name); if (binder != null) { return binder; } else { throw new ServiceNotFoundException(name); } } public static IBinder getService(String name) { try { // 各經常使用服務的代理對象已放入緩存,直接從緩存中取 IBinder service = sCache.get(name); if (service != null) { return service; } else { // 其餘很是用服務則再 經過 Binder IPC 來獲取 return Binder.allowBlocking(rawGetService(name)); } } catch (RemoteException e) { Log.e(TAG, "error in getService", e); } return null; } private static IBinder rawGetService(String name) throws RemoteException { ··· final IBinder binder = getIServiceManager().getService(name); ··· return binder; } 複製代碼
到此,整個系統 Services 的流程的代碼示例已經展現完。
ServiceManager
對象來管理系統 Services(或代理對象),用戶進程和
system_server
進程中的爲 java 對象(對應同一個
ServiceManager.java),
severmanager
進程則爲 native 對象(
service_manager.c 或
ServiceManager.cpp),也是整個 Binder 架構的服務管理中心。
本次的分享就到這啦,喜歡的話能夠點個贊 👍 或關注唄。若有錯誤的地方歡迎你們在評論裏指出。