Android中getSystemService流程

来源:互联网 发布:可以看亚丝娜本子软件 编辑:程序博客网 时间:2024/04/30 21:03

在平时的android开发中,我们经常会通过Context来获取系统服务,比如ActivityManagerService,AccountManagerService等系统服务,今天我们就来看下getSystemService(String name)的整个调用流程。

找到Context的实现类

打开Context类,可以看到Context是一个抽象类,那么getSystemService一定是在其实现类来调用的,具体我们都猜得到ContextImpl

public abstract class Context {  ......}

为什么是ContextImpl呢?我们都知道当我们启动一个Activity的时候,其实是在ActivityThread#performLaunchActivity方法中启动的,这一点可以参考上一篇文章” Activity启动流程 “,一个Activity的入口是
ActivityThread的main方法,看下main方法

public static void main(String[] args) {        .......        // 主线程消息循环        Looper.prepareMainLooper();        ActivityThread thread = new ActivityThread();        thread.attach(false);        if (sMainThreadHandler == null) {            sMainThreadHandler = thread.getHandler();        }        Looper.loop();        throw new RuntimeException("Main thread loop unexpectedly exited");}

可以看到上面在main方法中,调用了自身的attach方法。

private void attach(boolean system) {        ........        if (!system) {           final IActivityManager mgr = ActivityManagerNative.getDefault();            try {                // 通过binder获取到的ActivityManagerService关联当前mAppThread                mgr.attachApplication(mAppThread);            } catch (RemoteException ex) {                // Ignore            }}

可以看到在main方法中,通过调用activityThread的attach方法,并且参数为false,表示非系统应用,会通过binder与
ActivityManagerService通信,并且最后会调用performLaunchActivity方法。

private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {        Activity activity = null;        try {            java.lang.ClassLoader cl = r.packageInfo.getClassLoader();            activity = mInstrumentation.newActivity(                    cl, component.getClassName(), r.intent);            r.intent.setExtrasClassLoader(cl);            r.intent.prepareToEnterProcess();            if (r.state != null) {                r.state.setClassLoader(cl);            }        } catch (Exception e) {            ....        }        try {            Application app = r.packageInfo.makeApplication(false, mInstrumentation);            if (activity != null) {                // 创建Context的实例                Context appContext = createBaseContextForActivity(r, activity);                activity.attach(appContext, this, getInstrumentation(), r.token,                        r.ident, app, r.intent, r.activityInfo, title, r.parent,                        r.embeddedID, r.lastNonConfigurationInstances, config,                        r.referrer, r.voiceInteractor);                .......            }            r.paused = true;            mActivities.put(r.token, r);        } catch (SuperNotCalledException e) {            .....        }        return activity;    }

可以看到创建Context的具体实现是在ActivityThread#createBaseContextForActivity方法中完成的

private Context createBaseContextForActivity(ActivityClientRecord r, final Activity activity) {        // 可以看到这里创建的具体实例是ContextImpl        ContextImpl appContext = ContextImpl.createActivityContext(                this, r.packageInfo, displayId, r.overrideConfig);        appContext.setOuterContext(activity);        Context baseContext = appContext;        ......        return baseContext;}

好了,到现在位置我们可以看到Context的实现类就是ContextImpl,那么关于getSystemService的具体实现也应该在ContextImpl里面了。

getSystemService的具体实现

ContextImpl#getSystemService的实现如下

@Overridepublic Object getSystemService(String name) {    return SystemServiceRegistry.getSystemService(this, name);}

可以看到实际上ContextImpl也是通过SystemServiceRegistry.getSystemService来获取具体的服务,那么下面看看SystemServiceRegistry.getSystemService

public static Object getSystemService(ContextImpl ctx, String name) {        ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);        return fetcher != null ? fetcher.getService(ctx) : null;} private static final HashMap<String, ServiceFetcher<?>> SYSTEM_SERVICE_FETCHERS =            new HashMap<String, ServiceFetcher<?>>();

可看到实际上获取系统服务是通过ServiceFetcher的getService来获取的,并且SYSTEM_SERVICE_FETCHERS实际上就是一个Map实例,所以肯定是通过put方法为它赋值的。通过搜索,我们发现只有一个地方在做put操作:

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);}

顾名思义,这个方法是用来注册系统服务的,当注册系统服务的时候,就会调用到SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher);将当前的服务put到SYSTEM_SERVICE_NAMES集合中

static abstract interface ServiceFetcher<T> {        T getService(ContextImpl ctx);}

ServiceFetcher是一个接口,又三个实现类:CachedServiceFetcher,StaticServiceFetcher,StaticOuterContextServiceFetcher,具体不同的服务可能对应不同的实现类

这些系统服务都是在SystemServiceRegistry的static静态代码块中进行注册的,如下:

static {.....        registerService(Context.ACCOUNT_SERVICE, AccountManager.class,                new CachedServiceFetcher<AccountManager>() {            @Override            public AccountManager createService(ContextImpl ctx) {                IBinder b = ServiceManager.getService(Context.ACCOUNT_SERVICE);                IAccountManager service = IAccountManager.Stub.asInterface(b);                return new AccountManager(ctx, service);            }});        registerService(Context.ACTIVITY_SERVICE, ActivityManager.class,                new CachedServiceFetcher<ActivityManager>() {            @Override            public ActivityManager createService(ContextImpl ctx) {                return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler());            }});.....}

这里,我们以ActivityManagerService为例来进行学习。在注册该服务的时候,将Context.ACTIVITY_SERVICE作为键,将CachedServiceFetcher作为值,并且重写了createService方法,createService是在当前ServiceFetcher的
getService里执行的,这里会返回一个ActivityManager的实例,ctx.mMainThread.getHandler()就是ActivityThread中的H,在”activity 启动流程”一文,我们已经知道了,启动activity最终就会通过ActivityThread$H的handleMessage进行处理,实际上,包括service的启动以及Broadcast的处理都是在H里处理的,这个后面会细说。

在SystemServer中启动系统服务

我们知道android系统第一次开机的时候,会通过ZygoteInit来启动SystemServer,简单看下ZygoteInit#main方法

public static void main(String argv[]) {        try {            boolean startSystemServer = false;            for (int i = 1; i < argv.length; i++) {                // 通过系统传递过来的命令来判断是否需要启动运行SystemServer类                if ("start-system-server".equals(argv[i])) {                    startSystemServer = true;                }            }            if (startSystemServer) {                // 启动运行SystemServer类                startSystemServer(abiList, socketName);            }        }}

此时会执行SystemServer的main方法

public static void main(String[] args) {      new SystemServer().run();}

比较简单,内部运行自身的run方法

private void run() {        // 如果当前系统时间小于1970年,则设置为1970        if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {            SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);        }        // 设置默认的语言和地区        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", "");        }        // Mmmmmm... more memory!        VMRuntime.getRuntime().clearGrowthLimit();        // The system server has to run all of the time, so it needs to be        // as efficient as possible with its memory usage.        VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);        // Prepare the main looper thread (this thread).        android.os.Process.setThreadPriority(                android.os.Process.THREAD_PRIORITY_FOREGROUND);        android.os.Process.setCanSelfBackground(false);        Looper.prepareMainLooper();        // Initialize native services.        System.loadLibrary("android_servers");        // Check whether we failed to shut down last time we tried.        // This call may not return.        performPendingShutdown();        // Initialize the system context.        createSystemContext();        // Create the system service manager.        mSystemServiceManager = new SystemServiceManager(mSystemContext);        LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);        // 启动服务        try {            startBootstrapServices();            startCoreServices();            startOtherServices();        } catch (Throwable ex) {            throw ex;        }        // Loop forever.        Looper.loop();        throw new RuntimeException("Main thread loop unexpectedly exited");    }

在上面的run方法中,和service相关的操作主要就是通过下面的方法启动:开机,核心,以及其他服务

startBootstrapServices();startCoreServices();startOtherServices();

其实在这个三个start服务中,不止启动系统服务,还会将这些服务和ServiceManager进行关联,以方便ServiceManager的管理
比如:

ServiceManager.addService(Context.INPUT_SERVICE, inputManager);

好了,到这里为止,getSystemService的流程就走完了,作为自己的学习记录。如果又不对的地方,敬请指教。

0 0
原创粉丝点击