3

我一直在玩弄 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 方法,并且一切似乎都可以正常工作。

应用程序不能使用存根方法自然有安全原因,但它们使用存根方法进行系统服务肯定是有原因的。

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

4

1 回答 1

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 公开它。但最终,相同的代码最终会被执行。

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

于 2013-11-22T19:40:15.560 回答