Android AMS IPC代理獲取

一、問題

我們知道,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", 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);

        } 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
            );

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章