我的Android应用程序中的Java反射代码从包A调用包B中的公共静态方法。
最近,在对Gradle进行一些升级之后,我无法调用相同的方法。我的实现因NoSuchMethodFound异常而失败。如何获取实现才能找到此方法?
我尝试打印该类中所有可用的方法。结果是所有公共非静态方法。没有静态方法可用于调用。我要调用的方法是一个静态的“ getInstance”方法,该方法初始化该类并返回一个单例实例。
呼叫代码:
implementationClass = Class.forName(CLIENT_CLASS_NAME, false, ClientProvider.class.getClassLoader());
final Method method = implementationClass.getMethod("getInstance", (Class[]) null);
result = method.invoke(null, (Object[]) null);
被叫代码:
/**
* 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();
}
尝试“ getMethod”时,我收到一个NoSuchMethodException。
不知道我在这里做错了什么,感谢您的帮助。谢谢!
答案 0 :(得分:0)
如果我理解正确,则您使用了错误的反射API
只需尝试一下。
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);
}
}
它将正确放置结果
ClientImpl@<hashcode> with some -> 123
在反射API中使用静态方法时,无需显式调用ClassLoader,而必须将其canonicalName放在参数中,然后可以调用其方法。
答案 1 :(得分:0)
尝试替换它,也许是参数问题。
final Method method = implementationClass.getMethod("getInstance");
result = method.invoke(null);
答案 2 :(得分:0)
从Android 9(API级别28)开始,该平台限制了您的应用可以使用哪些非SDK接口。每当应用程序引用非SDK接口或尝试使用反射获取其句柄时,这些限制就会适用。
答案 3 :(得分:0)
结果证明,Proguard正在从构建中删除该方法,因为该方法未在其他地方使用。为课程添加了一个例外,问题就消失了。