ZygoteInit.java main 函數(shù)中
public?static?void?main(String argv[])?{
.....
if?(startSystemServer) {
Runnable r =?forkSystemServer(abiList, socketName, zygoteServer);
private?static?Runnable?forkSystemServer(String abiList, String socketName,
? ? ? ? ZygoteServer zygoteServer) {
.....
String args[] = {
?"--setuid=1000",
?"--setgid=1000",
?"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1023,1032,3001,3002,3003,3006,3007,3009,3010",
?"--capabilities="?+ capabilities +?","?+ capabilities,
?"--nice-name=system_server",
?"--runtime-args",
?"com.android.server.SystemServer",
};
.....
pid =?Zygote.forkSystemServer(
? ? ? ? ? ? parsedArgs.uid, parsedArgs.gid,
? ? ? ? ? ? parsedArgs.gids,
? ? ? ? ? ? parsedArgs.debugFlags,
?null,
? ? ? ? ? ? parsedArgs.permittedCapabilities,
? ? ? ? ? ? parsedArgs.effectiveCapabilities);
}?catch?(IllegalArgumentException ex) {
?throw?new?RuntimeException(ex);
}
........
/* For child process */
if?(pid ==?0) {
?if?(hasSecondZygote(abiList)) {
?waitForSecondaryZygote(socketName);
? ? }
? ? zygoteServer.closeServerSocket();
?return?handleSystemServerProcess(parsedArgs);
}
systemServer 啟動之后,干了什么 ?
1 啟用Binder機制
2 啟動各類系統(tǒng)服務(wù), 把這些服務(wù)的Binder對象注冊到sm
3 進入Loop循環(huán)
看一下?handleSystemServerProcess 這個函數(shù)
private?static?Runnable?handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs)?{
....
return?ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
看一下zygoteInit函數(shù),主要干了三件事情
public?static?final?Runnable?zygoteInit(int?targetSdkVersion, String[] argv, ClassLoader classLoader)?{
?if?(RuntimeInit.DEBUG) {
? ? ? ? Slog.d(RuntimeInit.TAG,?"RuntimeInit: Starting application from zygote");
? ? }
? ? Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,?"ZygoteInit");
? ? RuntimeInit.redirectLogStreams();
?RuntimeInit.commonInit();
?ZygoteInit.nativeZygoteInit();// 啟用binder機制,啟動了binder線程,用于跟其他進程比如app ,sm 通訊
?return?RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);// 調(diào)用一個SystemServer Java 類的入口函數(shù)
}
看一下nativeZygoteInit// AndroidRuntime.cpp
static?void?com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
? ? gCurRuntime->onZygoteInit();
}
webview_zygote.cpp
class?WebViewRuntime?:?public?AndroidRuntime {
public:
? ? WebViewRuntime(char* argBlockStart,?size_t?argBlockSize)
? ? ? ? : AndroidRuntime(argBlockStart, argBlockSize) {}
? ? ~WebViewRuntime() override {}
?void?onStarted()?override?{
?// Nothing to do since this is a zygote server.
? ? }
?void?onVmCreated(JNIEnv*)?override?{
?// Nothing to do when the VM is created in the zygote.
? ? }
?void?onZygoteInit()?override?{
?// Called after a new process is forked.
? ? ? ? sp<ProcessState> proc = ProcessState::self();
? ? ? ? proc->startThreadPool();
? ? }
看一下applicationInit方法
protected?static?Runnable?applicationInit(int?targetSdkVersion, String[] argv,
? ? ? ? ClassLoader classLoader) {
...
return?findStaticMain(args.startClass, args.startArgs, classLoader);// systemServer.main
看一下sytemServer的main函數(shù)
public?static?void?main(String[] args)?{
?new?SystemServer().run();
}
看一下這個run 函數(shù)
private?void?run()?{
?try?{
? ? ? ......
? ? ? ? Looper.prepareMainLooper();// 為主線程準(zhǔn)備一個Looper
?// Initialize native services.
?System.loadLibrary("android_servers");// 加載共享庫, systemserver系統(tǒng)服務(wù)的native層代碼
?// Check whether we failed to shut down last time we tried.
?// This call may not return.
?performPendingShutdown();
?// Initialize the system context.
?createSystemContext();// 創(chuàng)建系統(tǒng)上下文
...
?// Start services.
?try?{
?traceBeginAndSlog("StartServices");
? ? ? ? startBootstrapServices();
? ? ? ? startCoreServices();
? ? ? ? startOtherServices();
? ? ? ? SystemServerInitThreadPool.shutdown();
}?catch?(Throwable ex) {
? ? ? ? Slog.e("System",?"******************************************");
? ? ? ? Slog.e("System",?"************ Failure starting system services", ex);
?throw?ex;
}?finally?{
?traceEnd();
? ? }
?// For debug builds, log event loop stalls to dropbox for analysis.
?if?(StrictMode.conditionallyEnableDebugLogging()) {
? ? ? ? Slog.i(TAG,?"Enabled StrictMode for system server main thread.");
? ? }
?if?(!mRuntimeRestart?&& !isFirstBootOrUpgrade()) {
?int?uptimeMillis = (int) SystemClock.elapsedRealtime();
? ? ? ? MetricsLogger.histogram(null,?"boot_system_server_ready", uptimeMillis);
?final?int?MAX_UPTIME_MILLIS =?60?*?1000;
?if?(uptimeMillis > MAX_UPTIME_MILLIS) {
? ? ? ? ? ? Slog.wtf(SYSTEM_SERVER_TIMING_TAG,
?"SystemServer init took too long. uptimeMillis="?+ uptimeMillis);
? ? ? ? }
? ? }
?// Loop forever.
?Looper.loop();// 進入Loop循環(huán)
?throw?new?RuntimeException("Main thread loop unexpectedly exited");
}
如何發(fā)布系統(tǒng)服務(wù)?/systemserver進程啟動時啟動系統(tǒng)服務(wù)時,會把服務(wù)的Binder對象注冊到sm/ SytemService.java
/**
?* Publish the service so it is accessible to other services and apps.
?*/
protected?final?void?publishBinderService(String name, IBinder service)?{
publishBinderService(name, service,?false);
}
protected?final?void?publishBinderService(String name, IBinder service,
?boolean?allowIsolated) {
? ? ServiceManager.addService(name, service, allowIsolated);
}
public?static?void?addService(String name, IBinder service,?boolean?allowIsolated)?{
?try?{
?getIServiceManager().addService(name, service, allowIsolated);
}?catch?(RemoteException e) {
? ? ? ? Log.e(TAG,?"error in addService", e);
? ? }
}
如何使用系統(tǒng)服務(wù)?// ContextImpl.java
@Override
public?Object?getSystemService(String name)?{
?return?SystemServiceRegistry.getSystemService(this, name);
}
public?static?Object?getSystemService(ContextImpl ctx, String name)?{
ServiceFetcher fetcher =?SYSTEM_SERVICE_FETCHERS.get(name);// 根據(jù)名稱獲取ServiceFetcher hashmap
?return?fetcher !=?null?? fetcher.getService(ctx) :?null;
}
static?abstract?class?CachedServiceFetcher<T>?implements?ServiceFetcher<T>?{
?private?final?int?mCacheIndex;
?public?CachedServiceFetcher()?{
?mCacheIndex?=?sServiceCacheSize++;
? ? }
?@Override
?@SuppressWarnings("unchecked")
?public?final?T?getService(ContextImpl ctx)?{
?final?Object[] cache = ctx.mServiceCache;
?synchronized?(cache) {
?// Fetch or create the service.
?Object service = cache[mCacheIndex];
?if?(service ==?null) {
?try?{
? ? ? ? ? ? ? ? ? ? service = createService(ctx);
? ? ? ? ? ? ? ? ? ? cache[mCacheIndex] = service;
}?catch?(ServiceNotFoundException e) {
?onServiceNotFound(e);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
?return?(T)service;
? ? ? ? }
? ? }
?public?abstract?T?createService(ContextImpl ctx)?throws?ServiceNotFoundException;
}
registerService(Context.POWER_SERVICE, PowerManager.class,//SystemServiceRegisry.java, 以PowerManagerService為例子
?new?CachedServiceFetcher<PowerManager>() {
?@Override
?public?PowerManager?createService(ContextImpl ctx)?throws?ServiceNotFoundException?{
? ? ? ? IBinder b = ServiceManager.getServiceOrThrow(Context.POWER_SERVICE);// BpBinder對象
? ? ? ? IPowerManager service = IPowerManager.Stub.asInterface(b);
?return?new?PowerManager(ctx.getOuterContext(),
? ? ? ? ? ? ? ? service, ctx.mMainThread.getHandler());// 根據(jù)service 封裝成Powermanager對象,不用catch RemoteException,靜態(tài)代理實際上還是調(diào)用的service的函數(shù)
? ? }});
看一下getServiceOrThrow
public?static?IBinder?getServiceOrThrow(String name)?throws?ServiceNotFoundException?{
?final?IBinder binder =?getService(name);
?if?(binder !=?null) {
?return?binder;
}?else?{
?throw?new?ServiceNotFoundException(name);
? ? }
}
// 看一個getService 函數(shù)
public?static?IBinder?getService(String name)?{
?try?{
IBinder service =?sCache.get(name);// 緩存是用來放預(yù)制的IbInder對象,
?if?(service !=?null) {
?return?service;
}?else?{
?return?Binder.allowBlocking(getIServiceManager().getService(name));// 這一步并沒有放到緩存里
? ? ? ? }
}?catch?(RemoteException e) {
? ? ? ? Log.e(TAG,?"error in getService", e);
? ? }
?return?null;
}
不是所有的系統(tǒng)服務(wù)都跑在SystemServer進程里面的,比如SF,mediaserver,sm進程等,也需要注冊到sm,這樣別人才能找打它.
獨立進程的系統(tǒng)服務(wù):SF
service surfaceflinger?/system/bin/surfaceflinger// 進程啟動時加載的二進制文件路徑
?class?core?animation
? ? user system
? ? group graphics drmrpc readproc
? ? onrestart restart zygote
? ? writepid /dev/stune/foreground/tasks
看一個sf啟動時的main函數(shù)//main_surfaceflinger.cpp
int main(int, char**) {
? ? startHidlServices();
? ? signal(SIGPIPE, SIG_IGN);
?// When SF is launched in its own process, limit the number of
?// binder threads to 4.
? ? ProcessState::self()->setThreadPoolMaxThreadCount(4);
?// start the thread pool
? ? sp<ProcessState> ps(ProcessState::self());//ProcessState 的 構(gòu)造函數(shù)中啟用binder機制
? ? ps->startThreadPool();
?// instantiate surfaceflinger
? ? sp<SurfaceFlinger> flinger = DisplayUtils::getInstance()->getSFInstance();
setpriority(PRIO_PROCESS,?0, PRIORITY_URGENT_DISPLAY);
? ? set_sched_policy(0, SP_FOREGROUND);
?// Put most SurfaceFlinger threads in the system-background cpuset
?// Keeps us from unnecessarily using big cores
?// Do this after the binder thread pool init
?if?(cpusets_enabled()) set_cpuset_policy(0, SP_SMT_SYSTEM);
?// initialize before clients can connect
? ? flinger->init();
?// publish surface flinger
? ? sp<IServiceManager> sm(defaultServiceManager());
? ? sm->addService(String16(SurfaceFlinger::getServiceName()), flinger,?false);
?// publish GpuService
sp gpuservice =?new?GpuService();
sm->addService(String16(GpuService::SERVICE_NAME), gpuservice,?false);
? ? struct sched_param param = {0};
param.sched_priority =?2;
?if?(sched_setscheduler(0, SCHED_FIFO, ?m) !=?0) {
? ? ? ? ALOGE("Couldn't set SCHED_FIFO");
? ? }
?// run surface flinger in this thread
? ? flinger->run();// 進入Loop循環(huán)
?return?0;
}
系統(tǒng)服務(wù)和bind 的應(yīng)用服務(wù)有什么區(qū)別?
1 啟動方式:
啟動服務(wù),主要是做了服務(wù)的初始化工作,比如準(zhǔn)備好服務(wù)的binder的實體對象,當(dāng)client有請求過來時,就會在binder線程池中,把請求分發(fā)給對應(yīng)的binder實體對象,再回復(fù)給client端;binder線程中等待client請求,在分發(fā)給binder實體對象
系統(tǒng)服務(wù):啟動了AMS WMS PMS ?
client-->Binder線程池-->各個service ? ? ?
startBootstrapServices();
? ? ? ? startCoreServices();
? ? ? ? startOtherServices();
應(yīng)用服務(wù)的啟動,無論是startService/bindService,都是應(yīng)用端發(fā)起,都會調(diào)用到AMS
ConTextImpl.java
private?ComponentName?startServiceCommon(Intent service,?boolean?requireForeground,
? ? ? ? UserHandle user) {
?try?{
? ? ? ? validateServiceIntent(service);
? ? ? ? service.prepareToLeaveProcess(this);
? ? ? ? ComponentName cn = ActivityManager.getService().startService(// AMS 創(chuàng)建ServiceRecord,sr不是真正的service,只是service的記錄,Ams只負(fù)責(zé)service的管理和調(diào)度,真正service的啟動和加載還是需要在應(yīng)用端來做
?mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
? ? ? ? ? ? ? ? ? ? ? ? getContentResolver()), requireForeground,
? ? ? ? ? ? ? ? ? ? ? ? getOpPackageName(), user.getIdentifier());
// 看一下Ams的startService方法
public?ComponentName?startService(IApplicationThread caller, Intent service,
String resolvedType,?boolean?requireForeground, String callingPackage,?int?userId)
?throws?TransactionTooLargeException {
.....
res =?mServices.startServiceLocked(caller, service,
? ? ? ? resolvedType, callingPid, callingUid,
? ? ? ? requireForeground, callingPackage, userId);//mServices 是ActiveServices 的實例調(diào)用到了
......
startServiceLocked-->startServiceInnerLocked-->bringUpServiceLocked-->realStartServiceLocked-->
//ActivityService.java
private?final?void?realStartServiceLocked(ServiceRecord r,
ProcessRecord app,?boolean?execInFg)?throws?RemoteException {
....
app.thread.scheduleCreateService(r, r.serviceInfo,
?mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
? ? ? ? app.repProcState);
app.thread.scheduleCreateService 這個方法會調(diào)用到應(yīng)用端
應(yīng)用端是怎么做的?//ActivityThread.java
public?final?void?scheduleCreateService(IBinder token,
ServiceInfo info, CompatibilityInfo compatInfo,?int?processState) {
? ? AnrLogger.notesServiceTrack(info.name, token,?"create binder receive");
updateProcessState(processState,?false);
CreateServiceData s =?new?CreateServiceData();
? ? s.token?= token;
?s.info?= info;
? ? s.compatInfo?= compatInfo;
? ? sendMessage(H.CREATE_SERVICE, s);
}
// ActivityThread handleMessage方法
public?void?handleMessage(Message msg) {
......
case?CREATE_SERVICE:
? ? Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, ("serviceCreate: "?+ String.valueOf(msg.obj)));
?handleCreateService((CreateServiceData)msg.obj);
? ? Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
?break;
private?void?handleCreateService(CreateServiceData?data) {
?// If we are getting ready to gc after going to the background, well
?// we are back active so skip it.
?AnrLogger.notesServiceTrack(null,?data.token,?"create main receive");
? ? unscheduleGcIdler();
? ? LoadedApk packageInfo = getPackageInfoNoCheck(
?data.info.applicationInfo,?data.compatInfo);
Service service =?null;
?try?{
? ? ? ? java.lang.ClassLoader cl = packageInfo.getClassLoader();//加載service類
? ? ? ? service = (Service) cl.loadClass(data.info.name).newInstance();// 調(diào)用service的newInstance創(chuàng)建實例
}?catch?(Exception e) {
?if?(!mInstrumentation.onException(service, e)) {
?throw?new?RuntimeException(
?"Unable to instantiate service "?+?data.info.name
?+?": "?+ e.toString(), e);
? ? ? ? }
? ? }
?try?{
?if?(localLOGV) Slog.v(TAG,?"Creating service "?+?data.info.name);
ContextImpl?context?= ContextImpl.createAppContext(this, packageInfo);
? ? ? ? context.setOuterContext(service);// 給service 創(chuàng)建上下文
? ? ? ? Application app = packageInfo.makeApplication(false,?mInstrumentation);// 創(chuàng)建appli
?service.attach(context,?this,?data.info.name,?data.token, app,
? ? ? ? ? ? ? ? ActivityManager.getService());//給service 賦予上下文
? ? ? ? service.onCreate();// 執(zhí)行生命周期方法
?mServices.put(data.token, service);
?try?{
? ? ? ? ? ? ActivityManager.getService().serviceDoneExecuting(
?data.token,?SERVICE_DONE_EXECUTING_ANON,?0,?0);
? ? ? ? ? ? AnrLogger.notesServiceTrack(null,?data.token,?"create done");
}?catch?(RemoteException e) {
?throw?e.rethrowFromSystemServer();
? ? ? ? }
}?catch?(Exception e) {
?if?(!mInstrumentation.onException(service, e)) {
?throw?new?RuntimeException(
?"Unable to create service "?+?data.info.name
?+?": "?+ e.toString(), e);
? ? ? ? }
? ? }
}
2 注冊方式:
系統(tǒng)服務(wù) sm->addService // 注冊到serviceManger,不是任意的binder實體對象都能注冊到sm,應(yīng)用端的binder實體對象注冊到sm會提示權(quán)限錯誤,只有系統(tǒng)服務(wù)才能注冊到sm
應(yīng)用服務(wù): 應(yīng)用向AMS發(fā)起bindService調(diào)用, AMS先看service注冊過沒有,如果注冊過,就把service的binder對象返回給應(yīng)用,如果沒有注冊過,就向Service請求Binder對象,service響應(yīng)請求,把自己的binder對象注冊到AMS,然后AMS在把binder對象回調(diào)給應(yīng)用
3 使用方式:
系統(tǒng)服務(wù)的使用context.getSystemService(Context.POWER_SERVICE);
應(yīng)用服務(wù)通過bindService(serviceIntent, new ServiceCOnnection){
? ? ? ? public void onServiceConnected(ComponentName name, IBinder service) {
? ? ? ? ?IMyInterface myInterface = IMyInterface.Stub.asInterface(service);
? ? ? ? }
? ? ? ? public void onServiceDisconnected(ComponentName name) {
? ? ? ? }
}
SystemServer 里面,系統(tǒng)服務(wù)大概有70-80個,1 這些系統(tǒng)服務(wù)跑在什么線程?
主線程? // 一般不在,主線程啟動之后,就睡眠了
工作線程?// AMS wms pkms pmS有自己私有的工作線程,還有DisplayThread, FgThread,IoThread,UIThread(是一個子線程)等公共的工作線程
Binder線程?
大部分的服務(wù)都是跑在binder線程里面,只有少部分的服務(wù)有自己的工作線程
為什么系統(tǒng)服務(wù)不都跑在Binder線程里?
為什么系統(tǒng)服務(wù)不都跑在自己私有的工作線程里?
跑在BInder線程和跑在工作線程,如何取舍?
2 怎么解決系統(tǒng)服務(wù)啟動的相互依賴?
2-1 分批啟動,比較基礎(chǔ)的server 先啟動,比如AMS, PMS,PKMS... 很多service都依賴他們
2-2 分階段啟動, 階段1 ,階段2......