android reflection usage -- the usage of reflection method in IWIndowManager

Keywords: Android

If you don't say much, just go to the code. It's in the code meaning annotation

Method getRotation ;
Object IWindowManager ;
public void getRotation(){
        try {
            //Load to get the ServiceManager class, and then get the method getService.
            Method getServiceMethod = Class.forName("android.os.ServiceManager").getDeclaredMethod("getService", new Class[]{String.class});
            //Get the instance of ServiceManager through getServiceMethod (hide class, so use Object)
            Object ServiceManager = getServiceMethod.invoke(null, new Object[]{"window"});
            //Reflected to Stub
            Class<?> cStub =  Class.forName("android.view.IWindowManager$Stub");
            //Get asInterface method of Stub class
            Method asInterface = cStub.getMethod("asInterface", IBinder.class);
            //Then obtain the instance of IWindowManager through a method similar to serviceManager.getIWindowManager
            IWindowManager = asInterface.invoke(null, ServiceManager);
            //Get the method getRotation through the instance of IWindowManager
            getRotation = IWindowManager.getClass().getMethod("getRotation");

        } catch (Exception e) {
            Log.e("wmb", "--shutDown has an exception");
            e.printStackTrace();
        }
    }

When using the Method method, you only need to

int x = (int)getRotation.invoke(IWindowManager);

The last sentence to be noted here is IWindowManager.getClass().getMethod("getRotation"); the getMethod method in can have multiple parameters. Have a look at the source code

  private Method getMethod(String name, Class<?>[] parameterTypes, boolean recursivePublicMethods)
            throws NoSuchMethodException {
        if (name == null) {
            throw new NullPointerException("name == null");
        }
        if (parameterTypes == null) {
            parameterTypes = EmptyArray.CLASS;
        }
        for (Class<?> c : parameterTypes) {
            if (c == null) {
                throw new NoSuchMethodException("parameter type is null");
            }
        }
        Method result = recursivePublicMethods ? getPublicMethodRecursive(name, parameterTypes)
                                               : getDeclaredMethodInternal(name, parameterTypes);
        // Fail if we didn't find the method or it was expected to be public.
        if (result == null ||
            (recursivePublicMethods && !Modifier.isPublic(result.getAccessFlags()))) {
            throw new NoSuchMethodException(name + " " + Arrays.toString(parameterTypes));
        }
        return result;
    }

Here, the second parameter parameterTypes is the parameter type that this method needs to pass in. The third parameter is true by default.
For example, if the getRotation method needs to pass in parameters, it should

getRotation = IWindowManager.getClass().getMethod("getRotation",boolean.class,String.class);

When a method is called

int x = (int)getRotation.invoke(IWindowManager,false,"param");

If there is any mistake, please forgive me

Posted by pinochio on Sun, 05 Apr 2020 04:22:04 -0700