Android 用反射获取隐藏的WindowManagerService

系统里的WindowManagerService是被标记为hide的服务

/** {@hide} */
public class WindowManagerService extends IWindowManager.Stub

这就导致我们在导入WindowManagerService的时候会报错,提示找不到class
而且想直接用context.getSystemService也会得不到对象。

WindowManagerGlobal里有getWindowManagerService

IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
public static IWindowManager getWindowManagerService() {
    synchronized (WindowManagerGlobal.class) {
        if (sWindowManagerService == null) {
            sWindowManagerService = IWindowManager.Stub.asInterface(
                    ServiceManager.getService("window"));
            try {
                if (sWindowManagerService != null) {
                    ValueAnimator.setDurationScale(
                            sWindowManagerService.getCurrentAnimatorScale());
                }
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        }
        return sWindowManagerService;
    }
}

可是依然不行,导包要导入IWindowManager,而IWindowManager也是被标记为hide的

所以只能是用反射方法来获取对象

try {
   Method getServiceMethod = Class.forName("android.os.ServiceManager").getDeclaredMethod("getService", new Class[]{String.class});
   Object ServiceManager = getServiceMethod.invoke(null, new Object[]{"window"});
   Class<?> cStub =  Class.forName("android.view.IWindowManager$Stub");
   Method asInterface = cStub.getMethod("asInterface", IBinder.class);
   iWindowManager = asInterface.invoke(null, ServiceManager);
   setforcedDisplaySize = iWindowManager.getClass().getMethod("setForcedDisplaySize",int.class,int.class,int.class);
   clearForcedDisplaySize = iWindowManager.getClass().getMethod("clearForcedDisplaySize",int.class);
} catch (NoSuchMethodException e) {
   e.printStackTrace();
} catch (ClassNotFoundException e) {
   e.printStackTrace();
} catch (IllegalAccessException e) {
   e.printStackTrace();
} catch (InvocationTargetException e) {
   e.printStackTrace();
}

setForcedDisplaySize强制设置屏幕显示尺寸
displayId:默认为0

void setForcedDisplaySize(int displayId, int width, int height);

参数类型直接写 int.class

getMethod(“setForcedDisplaySize”,int.class,int.class,int.class);


时间:2019年4月19日10点22分

补充:系统app调用这种隐藏api其实不用反射也可以。

如果在app的Android.mk里有LOCAL_SDK_VERSION := current,就代表系统编译的时候会自动忽略hide的api,只需要去掉这个就可以了,比如在Launcher里,就有两个LOCAL_SDK_VERSION ,需要全部注释掉,就能编译通过。

#Don’t use LOCAL_SDK_VERSION.Because cann’t call hide APi
#in framework when has it.
#LOCAL_SDK_VERSION := current

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值