正确调用的反射API - Android电子 [英] Invoking reflection APIs correctly - Android
问题描述
我试图调用的WebView
的 getSelection
方法。我想使用Android中的反射API获取选定的文本。
I am trying to invoke the getSelection
method of WebView
. I am trying to use the reflection APIs in Android to get the selected text.
我已经延长的WebView
(新类名为 MyWebView
)来添加一些功能。该方法 getSelection
被调用像在 MyWebView
这样:
I have extended WebView
(the new class is named MyWebView
) to add some functionality. The method getSelection
is invoked like so within 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();
MyWebView
是一种非活性类。运行code会导致以下 LogCat中
输出:
MyWebView
is a non-Activity class. Running the code results in the following LogCat
output:
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.反射API中的引用
方法需要,我传给我打算调用该方法上作为第一个参数的类的对象。在这种情况下,这将是类的一个对象 MyWebView
。我怎么叫调用
与类型的对象 MyWebView
?结果
2.同样的code在 MyWebView
是活动的一部分的情况下效果很好
类。
My question is:
1. The invoke
method in the Reflection API requires that I pass the object of the class on which I intend to call the method on as the first argument. In this case, it would be an object of class MyWebView
. How do I call invoke
with an object of type MyWebView
?
2. The same code works well in a case where MyWebView
is part of the Activity
class.
推荐答案
例外表明你是一个匿名内部类里面。问题是,你不小心路过内部类的实例,而不是实例 EHWebView
的
The exception shows that you are inside of an anonymous inner class. The problem is that you are accidentally passing the instance of the inner class instead of the instance of EHWebView
.
您可以告诉你是一个内部类里面,因为经过正常的类名 EHWebView
,你会看到一个 $ 3
,它只是指第3匿名内部类 EHWebView
。这里是你带来的堆栈跟踪的相关部分:
You can tell that you are inside of an inner class because after the normal class name EHWebView
, you see a $3
, which simply refers to the 3rd anonymous inner class of EHWebView
. Here is the relevant part of the stack trace you posed:
08-16 19:15:22.745: W/System.err(23452): at com.englishhelper.bluebottle.EHWebView$3.onTouch(EHWebView.java:210)
通常情况下,匿名内部类的事件处理程序或可运行。他们经常出现,很多人甚至不知道他们正在使用他们。
Typically, anonymous inner classes are event handlers or runnables. They appear often and many people are not even aware they are using them.
您逝去的这个
到调用()
方法。中的内部类的,这个
指的是内部类,而不是外部类的实例的实例 EHWebView
You are passing this
to the invoke()
method. Inside of an inner class, this
refers to the instance of that inner class instead of the instance of the outer class EHWebView
.
要解决这个问题,通过删除通过外部类的引用这个
的而不是使用 EHWebView.this
To solve the problem, pass the reference of the outer class by removing this
an instead using EHWebView.this
:
str = (String) m.invoke(EHWebView.this, new Object[] { null });
这篇关于正确调用的反射API - Android电子的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!