正确调用反射API - Android

时间:2013-08-16 13:48:52

标签: java android reflection webview

我正在尝试调用getSelection的{​​{1}}方法。我试图在Android中使用反射API来获取所选文本。

我已扩展WebView(新类名为WebView)以添加一些功能。在MyWebView

中调用方法getSelection
MyWebView

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(); 是一个非Activity类。运行代码会产生以下MyWebView输出:

LogCat

我的问题是:
1. Reflection API中的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) 方法要求我将我打算调用方法的类的对象作为第一个参数传递。在这种情况下,它将是类invoke的对象。如何使用MyWebView类型的对象调用invoke? 2.在MyWebView类是MyWebView类的一部分的情况下,相同的代码效果很好。

1 个答案:

答案 0 :(得分:2)

该异常表明您在匿名内部类中。问题是您不小心传递了内部类的实例而不是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 });