我一直在和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方法,而看起来仍然可以很好地工作。
当然,应用程序不能使用存根方法是有安全原因的,但是它们使用存根方法用于系统服务肯定有一些原因。
因此,问题是为什么他们要使用Stub而不是上下文来获取其他系统服务?
发布于 2013-11-22 19:40:15
因此,在深入研究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公开它。但最终还是会执行相同的代码。
如果您是一个系统应用程序,通过存根获取服务可能会更快。
https://stackoverflow.com/questions/19325010
复制相似问题