正确调用的反射API - Android电子 [英] Invoking reflection APIs correctly - Android

查看:194
本文介绍了正确调用的反射API - 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆