Java 为什么不能通过反射找到带有布尔参数的方法?
我正在玩一些反射调用来调用一个通常对我隐藏的方法 我知道这不是好行为,但正如我所说的,我只是在胡闹 我使用以下代码检索并调用该方法:Java 为什么不能通过反射找到带有布尔参数的方法?,java,reflection,Java,Reflection,我正在玩一些反射调用来调用一个通常对我隐藏的方法 我知道这不是好行为,但正如我所说的,我只是在胡闹 我使用以下代码检索并调用该方法: ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); setData = ConnectivityManager.class.getDeclaredMethod("setMobileDataEnabled", B
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
setData = ConnectivityManager.class.getDeclaredMethod("setMobileDataEnabled", Boolean.class);
setData.setAccessible(true);
setData.invoke(cm, false);
这给了我一个例外:
03-02 12:21:40.411: ERROR/test(1052): java.lang.NoSuchMethodException: setMobileDataEnabled
03-02 12:21:40.411: ERROR/test(1052): at java.lang.ClassCache.findMethodByName(ClassCache.java:308)
03-02 12:21:40.411: ERROR/test(1052): at java.lang.Class.getDeclaredMethod(Class.java:748)
然后我尝试查看该方法是否在类中声明,并尝试查找所有方法并调用所需的方法:
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
Method[] methods = cm.getClass().getMethods();
for (Method method : methods) {
Log.d(Test.class.getSimpleName(), "Method name is: " + method.getName());
if (method.getName().equals("setMobileDataEnabled")) {
Log.d(Test.class.getSimpleName(), "Found method calling");
method.setAccessible(true);
method.invoke(cm, false);
}
}
这为我提供了以下输出:
03-02 12:19:41.851: DEBUG/Test(980): Method name is: getActiveNetworkInfo
03-02 12:19:41.851: DEBUG/Test(980): Method name is: getAllNetworkInfo
03-02 12:19:41.851: DEBUG/Test(980): Method name is: getBackgroundDataSetting
03-02 12:19:41.851: DEBUG/Test(980): Method name is: getLastTetherError
03-02 12:19:41.861: DEBUG/Test(980): Method name is: getMobileDataEnabled
03-02 12:19:41.861: DEBUG/Test(980): Method name is: getNetworkInfo
03-02 12:19:41.861: DEBUG/Test(980): Method name is: getNetworkPreference
03-02 12:19:41.861: DEBUG/Test(980): Method name is: getTetherableIfaces
03-02 12:19:41.861: DEBUG/Test(980): Method name is: getTetherableUsbRegexs
03-02 12:19:41.861: DEBUG/Test(980): Method name is: getTetherableWifiRegexs
03-02 12:19:41.861: DEBUG/Test(980): Method name is: getTetheredIfaces
03-02 12:19:41.871: DEBUG/Test(980): Method name is: getTetheringErroredIfaces
03-02 12:19:41.871: DEBUG/Test(980): Method name is: isTetheringSupported
03-02 12:19:41.871: DEBUG/Test(980): Method name is: requestRouteToHost
03-02 12:19:41.871: DEBUG/Test(980): Method name is: setBackgroundDataSetting
03-02 12:19:41.871: DEBUG/Test(980): Method name is: setMobileDataEnabled
03-02 12:19:41.871: DEBUG/Test(980): Found method calling
03-02 12:19:41.871: DEBUG/ConnectivityService(127): setMobileDataEnabled(false)
03-02 12:19:41.891: DEBUG/ConnectivityService(127): getMobileDataEnabled returning true
03-02 12:19:41.931: ERROR/Test(980): InvocationTargetException
03-02 12:19:41.931: ERROR/Test(980): java.lang.reflect.InvocationTargetException
03-02 12:19:41.931: ERROR/Test(980): at android.net.ConnectivityManager.setMobileDataEnabled(ConnectivityManager.java:379)
03-02 12:19:41.931: ERROR/Test(980): at java.lang.reflect.Method.invokeNative(Native Method)
03-02 12:19:41.931: ERROR/Test(980): at java.lang.reflect.Method.invoke(Method.java:521)
03-02 12:19:41.931: ERROR/Test(980): at Test(Test.java:84)
这个输出告诉我,方法
就在那里,我可以调用它,尽管事实上Android健全性检查已经开始,并且禁止调用更深层的系统方法
为什么通过
getDeclaredMethod
找不到该方法?是在ConnectionManager或父类上设置的setMobileDataEnabled
?看看getDeclaredMethod,我认为它需要在类本身上,而getMethod从整个继承树中获取方法。这个问题的两个可能原因,在不知道源代码的情况下无法确定:
- 参数类型实际上是
而不是Boolean
?不同的类型,可能不同的重载方法,这就是为什么像Boolean
这样的文本存在并且必须在这里使用boolean.class
- 这个方法是继承的吗
只查看类自己的方法,而不是继承的方法。您必须遍历类层次结构才能获得继承的方法getDeclaredMethod()
布尔值
(小写),但在代码中,您搜索的是布尔值
(大写)。如果参数类型为布尔值
(原语),请尝试此操作:
在AndroidManifest.xml中放置正确的使用权限
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
您遇到的问题是安全问题。
InvocationTargetException
包装“真实”异常,您需要向我们显示整个堆栈跟踪。堆栈跟踪不相关,它只显示找到并调用了该方法,请尝试传递boolean.class而不是boolean.classI。但随你的便。我在2.2.1上得到了InvocationTargetException,因为未授予权限写入的SecurityException\u SECURE\u设置您是对的,我使用boolean.class看起来太不自然了,我甚至没有尝试。参数为布尔值,反射中的自动装箱不适用;)
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />