如何从 Android 中的 ServiceManager 获取服务?
How to get a service from ServiceManager in Android?
我对 ServiceManager 注册的服务有疑问,而 SystemServiceRegistry 没有注册。
的评论中
/**
* Manages all of the system services that can be returned by {@link Context#getSystemService}.
* Used by {@link ContextImpl}.
*/
也就是说System注册的服务可以从Context中得到他的引用
关注 ServiceManager,我如何在未通过 SystemServiceRegistry 注册的应用程序中访问 ServiceManager 添加的服务?
正如@CommonsWare 正确提到的,您需要在上下文中使用 getSystemService()。
例如。获取定位服务:
LocationManager mLocationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
对于您的自定义服务使用(假设您的服务已在 AndroidManifest.xml 中注册):
startService(new Intent(this, YourServiceClass.class));
这个答案确实晚了,但是另一种访问 Hidden class ServiceManager 上的方法的方法是使用反射。由于 class 上的所有方法都是静态的,因此您不需要将对象引用传递给 invoke 方法。您可以简单地传入 class 实例。为了在隐藏的 class 上获得 class 实例,您可以使用更多的反射。
示例:
Class localClass = Class.forName("android.os.ServiceManager");
Method getService = localClass.getMethod("getService", new Class[] {String.class});
if(getService != null) {
Object result = getService.invoke(localClass, new Object[]{Context.AUDIO_SERVICE});
if(result != null) {
IBinder binder = (IBinder) result;
// DO WHAT EVER YOU WANT AT THIS POINT, YOU WILL
// NEED TO CAST THE BINDER TO THE PROPER TYPE OF THE SERVICE YOU USE.
}
}
这几乎就是访问隐藏或私有方法所需要做的全部工作(尽管使用私有方法,您需要修改方法的访问权限)。
我知道反射在 Android 中是不好的,它们通常是一些 API 没有暴露的充分理由,但有一些有效的用例可以使用它。如果您不经常调用反射代码,性能影响并不严重,如果您是,您可以缓存这些方法,这样您就不必在每次调用时都执行查找。话虽如此,如果您真的需要访问非 public API 的
,请小心并分析
我对 ServiceManager 注册的服务有疑问,而 SystemServiceRegistry 没有注册。
的评论中/**
* Manages all of the system services that can be returned by {@link Context#getSystemService}.
* Used by {@link ContextImpl}.
*/
也就是说System注册的服务可以从Context中得到他的引用
关注 ServiceManager,我如何在未通过 SystemServiceRegistry 注册的应用程序中访问 ServiceManager 添加的服务?
正如@CommonsWare 正确提到的,您需要在上下文中使用 getSystemService()。 例如。获取定位服务:
LocationManager mLocationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
对于您的自定义服务使用(假设您的服务已在 AndroidManifest.xml 中注册):
startService(new Intent(this, YourServiceClass.class));
这个答案确实晚了,但是另一种访问 Hidden class ServiceManager 上的方法的方法是使用反射。由于 class 上的所有方法都是静态的,因此您不需要将对象引用传递给 invoke 方法。您可以简单地传入 class 实例。为了在隐藏的 class 上获得 class 实例,您可以使用更多的反射。 示例:
Class localClass = Class.forName("android.os.ServiceManager");
Method getService = localClass.getMethod("getService", new Class[] {String.class});
if(getService != null) {
Object result = getService.invoke(localClass, new Object[]{Context.AUDIO_SERVICE});
if(result != null) {
IBinder binder = (IBinder) result;
// DO WHAT EVER YOU WANT AT THIS POINT, YOU WILL
// NEED TO CAST THE BINDER TO THE PROPER TYPE OF THE SERVICE YOU USE.
}
}
这几乎就是访问隐藏或私有方法所需要做的全部工作(尽管使用私有方法,您需要修改方法的访问权限)。 我知道反射在 Android 中是不好的,它们通常是一些 API 没有暴露的充分理由,但有一些有效的用例可以使用它。如果您不经常调用反射代码,性能影响并不严重,如果您是,您可以缓存这些方法,这样您就不必在每次调用时都执行查找。话虽如此,如果您真的需要访问非 public API 的
,请小心并分析