Android AMS IPC代理获取

原创
03/27 15:44
阅读数 62

一、问题

我们知道,ActivityManagerService随着版本的变化,获取方式上也出现了差异,最容易获取的方式当然是

ActivityManager activityManager = Context.getSystemService("activity");

但是,这种方式获取到ActivityManager存在很多限制,导致无法和AMS通信,那么还有没其他方式?

 

二,获取方式

1、关于ServiceManager

我们知道,ServiceManager是早于Zygote_Server和System_Server,我们可以提前获取的服务很多。而AMS在System_server进程中运行,后期将服务注册到ServceManager,本质上ServiceManager是系统服务的路由角色

2、如何获取呢,方法如下


public Object getActivityManagerProxy(){

     final Class<?> serviceManagerClazz = Class.forName("android.os.ServiceManager");
            final Method getServiceMethod  = 
     serviceManagerClazz.getMethod("getService",IBinder.class);
            final IBinder activityBinder = (IBinder) getServiceMethod.invoke(serviceManagerClazz, "activity");

     Class<?> activityManagerStu =  Class.forName("android.app.IActivityManager$Stub");
     Method asInterface = activityManagerStu.getMethod("asInterface",IBinder.class);

    return asInterface.invoke(activityManagerStu,activityBinder);

}

3、事实上上述方法存在缺陷

因为在Android O之前,AMS继承自ActivityManagerNative, 虽然这个类在用户进程可见,而且在ActivityThread中进行了注册,但并不能满足我们的要求。不过倒是一种获取BinderProxy的途径。

AMS 不存在IActivityManager.Stub,而使用的android.os.ActivityManagerProxy,我们需要做一下兼容即可


    public static Object getActivityManagerProxy(){
        try {
            if(Build.VERSION.SDK_INT< Build.VERSION_CODES.N){
                Class activityManagerNativeClass = Class.forName("android.app.ActivityManagerNative");
                Method getDefault = activityManagerNativeClass.getDeclaredMethod("getDefault");
                return getDefault.invoke(null);
            }
            final Class<?> serviceManagerClazz = Class.forName("android.os.ServiceManager");
            final Method getServiceMethod = serviceManagerClazz.getMethod("getService", String.class);
            final IBinder activityBinder = (IBinder) getServiceMethod.invoke(serviceManagerClazz, "activity");

            Class<?> activityManagerStu = Class.forName("android.app.IActivityManager$Stub");
            Method asInterface = activityManagerStu.getMethod("asInterface", IBinder.class);
            return asInterface.invoke(activityManagerStu, activityBinder);

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        return null;
    }

三、测试

Method startService =  activityManagerProxy.getClass().getDeclaredMethod("startService",
                    Class.forName("android.app.IApplicationThread"),
                    Intent.class,
                    String.class,
                    String.class,
                    int.class
            );

 

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部