2013-08-16 3 views
3

getSelection 메서드를 WebView으로 호출하려고합니다. 선택한 텍스트를 가져 오기 위해 Android에서 리플렉션 API를 사용하려고합니다.리플렉션 API를 올바르게 호출 - Android

일부 기능을 추가하기 위해 WebView (새 클래스의 이름은 MyWebView)입니다. 방법 getSelectionMyWebView 내과 같이 호출 :

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은 비 활동 클래스입니다. 다음 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. 리플렉션 API의 invoke 방법은 내가의 메소드를 호출하고자하는 클래스의 객체를 전달해야합니다 첫 번째 인수로. 이 경우 클래스 MyWebView의 객체가됩니다. 유형 MyWebView의 객체로 invoke으로 전화하려면 어떻게해야합니까?
MyWebViewActivity 클래스의 일부인 경우 동일한 코드가 잘 작동합니다.

답변

2

예외는 사용자가 익명의 내부 클래스에 있음을 보여줍니다. 문제는 실수로 EHWebView 인스턴스 대신 내부 클래스의 인스턴스를 전달하는 것입니다.

당신은 단순히 EHWebView의 3 익명의 내부 클래스를 의미하는, 당신이하는 $3 볼이 때문에 일반 클래스 이름 EHWebView 후 내부 클래스의 내부에 있음을 알 수 있습니다. 다음은 스택 추적의 관련 부분입니다.

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

일반적으로 익명 내부 클래스는 이벤트 처리기 또는 실행 파일입니다. 그들은 자주 나타나고 많은 사람들은 심지어 그들이 그것을 사용하고 있다는 것을 모르고 있습니다.

thisinvoke() 방법으로 전달 중입니다. 내부 클래스의 내부에서 this은 외부 클래스 EHWebView의 인스턴스 대신 해당 내부 클래스의 인스턴스를 참조합니다.

대신 EHWebView.this를 사용 this을 제거하여 외부 클래스 참조를 전달 문제를 해결하려면

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