当前位置:   article > 正文

Android中getSystemService流程_android getsystemservice

android getsystemservice

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

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

public abstract class Context {
  ......
}
  • 1
  • 2
  • 3

为什么是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");
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

可以看到上面在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
            }
     
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

可以看到在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;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

可以看到创建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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

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

@Override
public Object getSystemService(String name) {
    return SystemServiceRegistry.getSystemService(this, name);
}
  • 1
  • 2
  • 3
  • 4

可以看到实际上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<?>>();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

可看到实际上获取系统服务是通过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);
}
  • 1
  • 2
  • 3
  • 4
  • 5

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

static abstract interface ServiceFetcher<T> {
        T getService(ContextImpl ctx);
}
  • 1
  • 2
  • 3

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());
            }});
.....
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

这里,我们以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);
            }

        }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

此时会执行SystemServer的main方法

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

比较简单,内部运行自身的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");
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54

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

startBootstrapServices();
startCoreServices();
startOtherServices();
  • 1
  • 2
  • 3

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

ServiceManager.addService(Context.INPUT_SERVICE, inputManager);
  • 1

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

欢 迎 关 注 我 的 公 众 号 “编 程 大 全”

专注技术分享,包括Java,python,AI人工智能,Android分享,不定期更新学习视频
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/311059?site
推荐阅读
相关标签
  

闽ICP备14008679号