java - 正确调用反射API - Android

标签 java android reflection webview

我正在尝试调用 WebViewgetSelection 方法。我正在尝试使用 Android 中的反射 API 来获取选定的文本。

我扩展了 WebView(新类名为 MyWebView)以添加一些功能。在 MyWebView 中调用方法 getSelection:

for(Method m : WebView.class.getDeclaredMethods()) {
    if(m.getName().equalsIgnoreCase("getSelection")) {
        m.setAccessible(true);
        String str;
        try {
            Log.v(this.toString(), "is getSelection available? " + m.getModifiers() + " " + m.isAccessible());
            str = (String) m.invoke(this, new Object[] { null });
            Log.v(this.toString(), "String selected = " + str);
            Toast.makeText(context, str, Toast.LENGTH_LONG).show();  

MyWebView 是一个非 Activity 类。运行代码会产生以下 LogCat 输出:

08-16 19:15:22.745: W/System.err(23452): java.lang.IllegalArgumentException: object is not an instance of the class
08-16 19:15:22.745: W/System.err(23452):    at java.lang.reflect.Method.invokeNative(Native Method)
08-16 19:15:22.745: W/System.err(23452):    at java.lang.reflect.Method.invoke(Method.java:507)
08-16 19:15:22.745: W/System.err(23452):    at com.englishhelper.bluebottle.EHWebView$3.onTouch(EHWebView.java:210)
08-16 19:15:22.745: W/System.err(23452):    at android.view.View.dispatchTouchEvent(View.java:3934)
08-16 19:15:22.745: W/System.err(23452):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:903)
08-16 19:15:22.745: W/System.err(23452):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:942)
08-16 19:15:22.745: W/System.err(23452):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:942)
08-16 19:15:22.745: W/System.err(23452):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:942)
08-16 19:15:22.745: W/System.err(23452):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:942)
08-16 19:15:22.745: W/System.err(23452):    at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1730)
08-16 19:15:22.745: W/System.err(23452):    at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1142)
08-16 19:15:22.745: W/System.err(23452):    at android.app.Activity.dispatchTouchEvent(Activity.java:2102)
08-16 19:15:22.745: W/System.err(23452):    at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1714)
08-16 19:15:22.745: W/System.err(23452):    at android.view.ViewRoot.deliverPointerEvent(ViewRoot.java:2218)
08-16 19:15:22.745: W/System.err(23452):    at android.view.ViewRoot.handleMessage(ViewRoot.java:1889)
08-16 19:15:22.745: W/System.err(23452):    at android.os.Handler.dispatchMessage(Handler.java:99)
08-16 19:15:22.745: W/System.err(23452):    at android.os.Looper.loop(Looper.java:123)
08-16 19:15:22.745: W/System.err(23452):    at android.app.ActivityThread.main(ActivityThread.java:3691)
08-16 19:15:22.745: W/System.err(23452):    at java.lang.reflect.Method.invokeNative(Native Method)
08-16 19:15:22.745: W/System.err(23452):    at java.lang.reflect.Method.invoke(Method.java:507)
08-16 19:15:22.745: W/System.err(23452):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:847)
08-16 19:15:22.745: W/System.err(23452):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:605)
08-16 19:15:22.745: W/System.err(23452):    at dalvik.system.NativeStart.main(Native Method)

我的问题是:
1. Reflection API 中的invoke 方法要求我将要调用该方法的类的对象作为第一个参数传递。在这种情况下,它将是类 MyWebView 的一个对象。如何使用 MyWebView 类型的对象调用 invoke
2. 相同的代码在 MyWebViewActivity 类的一部分的情况下运行良好。

最佳答案

异常显示您在匿名内部类中。问题是您不小心传递了内部类的实例而不是 EHWebView 的实例。

你可以看出你在一个内部类中,因为在普通类名 EHWebView 之后,你会看到一个 $3,它简单地引用了第三个匿名内部类EHWebView。这是您提出的堆栈跟踪的相关部分:

08-16 19:15:22.745: W/System.err(23452):    at com.englishhelper.bluebottle.EHWebView$3.onTouch(EHWebView.java:210)

通常,匿名内部类是事件处理程序或可运行对象。它们经常出现,许多人甚至不知道他们在使用它们。

您正在将 this 传递给 invoke() 方法。在内部类内部,this 引用该内部类的实例,而不是外部类 EHWebView 的实例。

要解决这个问题,通过删除 this 并使用 EHWebView.this 来传递外部类的引用:

        str = (String) m.invoke(EHWebView.this, new Object[] { null });

关于java - 正确调用反射API - Android,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18274891/

相关文章:

java - 为什么在实例(Java)上调用方法时不需要导入类

java - 彼得森锁/解锁java实现

android - Android 中最后一行 GridView 的布局问题

java - 使用 SQLite 在 android 中获取下一个值

c# - 使用反射更新列表中的值

reflection - 编译型动态语言

java - Firebase 云消息传递 - onMessageReceived 不工作

java - LeanFT 并在多个浏览器中进行测试

android - 通过 Google Play Developer API 删除 Android 订阅列表

c# - 使用反射创建命名空间中所有类的列表并转换为其真实类型