Android中getSystemService流程

32 篇文章 0 订阅
29 篇文章 16 订阅

在平时的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的实现如下

@Override
public 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的流程就走完了,作为自己的学习记录。如果又不对的地方,敬请指教。

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

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

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值