systemServer进程

ZygoteInit.java main 函数中

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 启动各类系统服务, 把这些服务的Binder对象注册到sm

3 进入Loop循环

看一下 handleSystemServerProcess 这个函数

private static Runnable handleSystemServerProcess(ZygoteConnection.Arguments parsedArgs) {

....

return ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);

看一下zygoteInit函数,主要干了三件事情

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);// 调用一个SystemServer Java 类的入口函数

}

看一下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函数

public static void main(String[] args) {

 new SystemServer().run();

}

看一下这个run 函数

private void run() {

 try {

      ......

        Looper.prepareMainLooper();// 为主线程准备一个Looper

 // Initialize native services.

 System.loadLibrary("android_servers");// 加载共享库, systemserver系统服务的native层代码

 // Check whether we failed to shut down last time we tried.

 // This call may not return.

 performPendingShutdown();

 // Initialize the system context.

 createSystemContext();// 创建系统上下文

...

 // 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循环

 throw new RuntimeException("Main thread loop unexpectedly exited");

}

如何发布系统服务?/systemserver进程启动时启动系统服务时,会把服务的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);

    }

}

如何使用系统服务?// 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);// 根据名称获取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());// 根据service 封装成Powermanager对象,不用catch RemoteException,静态代理实际上还是调用的service的函数

    }});

看一下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 函数

public static IBinder getService(String name) {

 try {

IBinder service = sCache.get(name);// 缓存是用来放预制的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;

}

不是所有的系统服务都跑在SystemServer进程里面的,比如SF,mediaserver,sm进程等,也需要注册到sm,这样别人才能找打它.

独立进程的系统服务: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函数//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 的 构造函数中启用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循环

 return 0;

}

系统服务和bind 的应用服务有什么区别?

1 启动方式:

启动服务,主要是做了服务的初始化工作,比如准备好服务的binder的实体对象,当client有请求过来时,就会在binder线程池中,把请求分发给对应的binder实体对象,再回复给client端;binder线程中等待client请求,在分发给binder实体对象

系统服务:启动了AMS WMS PMS  

client-->Binder线程池-->各个service      

startBootstrapServices();

        startCoreServices();

        startOtherServices();

应用服务的启动,无论是startService/bindService,都是应用端发起,都会调用到AMS

ConTextImpl.java

private ComponentName startServiceCommon(Intent service, boolean requireForeground,

        UserHandle user) {

 try {

        validateServiceIntent(service);

        service.prepareToLeaveProcess(this);

        ComponentName cn = ActivityManager.getService().startService(// AMS 创建ServiceRecord,sr不是真正的service,只是service的记录,Ams只负责service的管理和调度,真正service的启动和加载还是需要在应用端来做

 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 的实例调用到了

......

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 这个方法会调用到应用端

应用端是怎么做的?//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();// 调用service的newInstance创建实例

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 创建上下文

        Application app = packageInfo.makeApplication(falsemInstrumentation);// 创建appli

 service.attach(context, this, data.info.name, data.token, app,

                ActivityManager.getService());//给service 赋予上下文

        service.onCreate();// 执行生命周期方法

 mServices.put(data.token, service);

 try {

            ActivityManager.getService().serviceDoneExecuting(

 data.tokenSERVICE_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 注册方式:

系统服务 sm->addService // 注册到serviceManger,不是任意的binder实体对象都能注册到sm,应用端的binder实体对象注册到sm会提示权限错误,只有系统服务才能注册到sm

应用服务: 应用向AMS发起bindService调用, AMS先看service注册过没有,如果注册过,就把service的binder对象返回给应用,如果没有注册过,就向Service请求Binder对象,service响应请求,把自己的binder对象注册到AMS,然后AMS在把binder对象回调给应用

3 使用方式:

系统服务的使用context.getSystemService(Context.POWER_SERVICE);

应用服务通过bindService(serviceIntent, new ServiceCOnnection){

        public void onServiceConnected(ComponentName name, IBinder service) {

         IMyInterface myInterface = IMyInterface.Stub.asInterface(service);


        }

        public void onServiceDisconnected(ComponentName name) {

        }

}

SystemServer 里面,系统服务大概有70-80个,1 这些系统服务跑在什么线程?

主线程? // 一般不在,主线程启动之后,就睡眠了

工作线程?// AMS wms pkms pmS有自己私有的工作线程,还有DisplayThread, FgThread,IoThread,UIThread(是一个子线程)等公共的工作线程

Binder线程?

大部分的服务都是跑在binder线程里面,只有少部分的服务有自己的工作线程

为什么系统服务不都跑在Binder线程里?

为什么系统服务不都跑在自己私有的工作线程里?

跑在BInder线程和跑在工作线程,如何取舍?

2 怎么解决系统服务启动的相互依赖?

2-1 分批启动,比较基础的server 先启动,比如AMS, PMS,PKMS... 很多service都依赖他们

2-2 分阶段启动, 阶段1 ,阶段2......

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343