AOSP Stubs vs getSystemService

时间:2013-10-11 18:34:00

标签: android android-source

我一直在玩AOSP,我注意到了一些关于系统服务的事情。他们中的很多人喜欢直接使用系统服务存根:

IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
                ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));

这样做而不是使用mContext请求它们,如下所示:

DevicePolicyManager dpm = (DevicePolicyManager)  
     context.getSystemService(Context.DEVICE_POLICY_SERVICE);

现在起初我认为可能是因为没有可用的上下文但是有。一个很好的例子是deletePackageX方法,它是PackageManagerService类的一部分。您可以将存根方法更改为getSystemService方法,并且所有内容仍然 SEEMS 可以正常工作。

当然,出于安全原因,为什么应用程序不能使用存根方法,但必须有一些原因,他们正在使用存根方法进行系统服务。

所以问题是为什么他们在上下文中使用Stubs获取其他系统服务?

1 个答案:

答案 0 :(得分:1)

因此,在深入了解ContextImpl.java以查看getSystemService调用正在做什么之后,它实际上只是您经常在系统服务中看到的Stub.asInterface调用的包装器。因此,当您创建系统服务并希望将其暴露给SDK时,您需要将其注册到上下文中,以便非系统应用程序能够处理它。大多数服务的注册都是这样的:

registerService(ALARM_SERVICE, new ServiceFetcher() {
                public Object createService(ContextImpl ctx) {
                    IBinder b = ServiceManager.getService(ALARM_SERVICE);
                    IAlarmManager service = IAlarmManager.Stub.asInterface(b);
                    return new AlarmManager(service, ctx);
                }});

看起来很熟悉?但是,当您获得系统服务时,服务提取器将执行一些其他开销,例如缓存您的服务,以便您可以在后续调用中更快地恢复它。 (那里有更多的开销,我没有详细研究,但我认为是为了优化)

所以基本上,通过存根直接获取服务,您可以节省开销,并且比通过上下文更快地执行操作。上下文仅存在,以便非系统应用程序可以访问您的服务,并且您希望通过SDK公开它。但最终,相同的代码最终会被执行。

如果您是系统应用程序,通过存根获取服务可能会更快。