简体   繁体   English

Android Studio上的Java Reflection无法找到要调用的公共静态方法

[英]Java Reflection on Android Studio unable to find public static method to invoke

The Java reflection code in my Android application invokes a public static method in a package B, from a package A. 我的Android应用程序中的Java反射代码从程序包A调用程序包B中的公共静态方法。

Recently, after some Gradle upgrades, I am unable to invoke the same method. 最近,在对Gradle进行了一些升级之后,我无法调用相同的方法。 My implementation fails with a NoSuchMethodFound exception. 我的实现因NoSuchMethodFound异常而失败。 How can I get the implementation to be able to find this method? 如何获得实现才能找到此方法?

I've tried printing all the available methods from the class. 我尝试从类中打印所有可用的方法。 The result is all public non-static methods. 结果是所有公共非静态方法。 No static methods are available to be invoked. 没有静态方法可用于调用。 The method I want to invoke is a static "getInstance" method which initializes the class and returns a singleton instance. 我要调用的方法是一个静态的“ getInstance”方法,该方法初始化该类并返回一个单例实例。

Calling Code: 呼叫代码:

implementationClass = Class.forName(CLIENT_CLASS_NAME, false, ClientProvider.class.getClassLoader());
final Method method = implementationClass.getMethod("getInstance", (Class[]) null);
result = method.invoke(null, (Object[]) null);

Called Code: 调用代码:

/**
* Public static method to be reflected.
*/
public static ClientImpl getInstance() {
    return ClientImplHolder.INSTANCE;
}

/**
 * Private class used to hold the lazily initialized singleton instance.
 */
private static class ClientImplHolder {
    private static final ClientImpl INSTANCE = new ClientImpl();
}

When attempting to 'getMethod', I receive a NoSuchMethodException. 尝试“ getMethod”时,我收到一个NoSuchMethodException。

Not sure what I am doing wrong here, appreciate any help. 不知道我在这里做错了,感谢您的帮助。 Thanks! 谢谢!

If i understood correctly, you used reflection API wrong 如果我理解正确,则您使用了反射API错误

just try this. 只是尝试这个。

public class Test {

    public static void main(String[] args) {
        try {
            ClientImpl client = (ClientImpl) Class.forName(ClientImpl.class.getCanonicalName())
                    .getMethod("getInstance")
                    .invoke(null);

            System.out.println(client.toString() + " with some -> " + client.getSome());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

/**
 * Public static method to be reflected.
 */

class ClientImpl {

    private final int some;

    public int getSome() {
        return some;
    }

    private ClientImpl(int some) {
        this.some = some;
    }

    public static ClientImpl getInstance() {
        return ClientImplHolder.INSTANCE;
    }

    /**
     * Private class used to hold the lazily initialized singleton instance.
     */
    private static class ClientImplHolder {
        private static final ClientImpl INSTANCE = new ClientImpl(123);
    }
}

and it will put correctly result 它会正确放置结果

ClientImpl@<hashcode> with some -> 123

When you use static methods in reflection API, you don't need to call it ClassLoader explicitly, you have to put it's canonicalName in argument, then you can call it's methods. 在反射API中使用静态方法时,无需显式调用它,而必须在参数中放入canonicalName,然后可以调用它的方法。

Try to replace it,maybe it's a parameter problem. 尝试更换它,也许是参数问题。

    final Method method = implementationClass.getMethod("getInstance");
    result = method.invoke(null);

Starting in Android 9 (API level 28), the platform restricts which non-SDK interfaces your app can use. 从Android 9(API级别28)开始,该平台会限制您的应用可以使用哪些非SDK接口。 These restrictions apply whenever an app references a non-SDK interface or attempts to obtain its handle using reflection. 每当应用程序引用非SDK接口或尝试使用反射获取其句柄时,便会应用这些限制。

Turns out Proguard was removing the method from the build since it was not being used elsewhere. 事实证明,Proguard正在从构建中删除该方法,因为该方法未在其他地方使用。 Added an exception for the class and the issue went away. 为课程添加了一个例外,问题就消失了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM