2012-11-27 2 views
0

Reflection 개념을 사용하여 MediaController 클래스에있는 FastForward Button의 가시성을 변경하려고합니다.Reflection을 사용하여 MediaController 필드에 액세스 할 수 없습니다.

다음은 제 코드입니다.

package com.example.reflection; 

import java.lang.reflect.Field; 
import android.app.Activity; 
import android.os.Bundle; 
import android.os.Environment; 
import android.view.View; 
import android.widget.ImageButton; 
import android.widget.MediaController; 
import android.widget.Toast; 
import android.widget.VideoView; 

public class MainActivity extends Activity { 

    private VideoView videoView; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     Class <? > aClass; 

     try { 

      MediaController controller = new MediaController(this); 

      aClass = Class.forName("android.widget.MediaController"); 

      Field forwardButton = aClass.getDeclaredField("mFfwdButton"); 
      forwardButton.setAccessible(true); 

NPE--->> ImageButton button = (ImageButton) forwardButton.get(controller); 

      if (null == button) Toast.makeText(this, "Button is null", Toast.LENGTH_LONG) 
       .show(); 
      else button.setVisibility(View.INVISIBLE); 

      videoView = (VideoView) findViewById(R.id.videoView); 
      videoView.setVideoPath(Environment.getExternalStorageDirectory() + "/Video/NeYo.flv"); 
      videoView.setMediaController(controller); 
      videoView.requestFocus(); 

     } catch (ClassNotFoundException e) { 
      e.printStackTrace(); 
     } catch (NoSuchFieldException e) { 
      e.printStackTrace(); 
     } catch (IllegalArgumentException e) { 
      e.printStackTrace(); 
     } catch (IllegalAccessException e) { 
      e.printStackTrace(); 
     } 

    } 
} 

ImageButton을 가져 오는 동안 NullPointerException이 발생합니다.

누군가 내가 지적한 오류를 지적 할 수 있습니까?

감사

는 어쨌든 나는이 질문에 대한 대답을 얻었다.

mFfwdButton은 뷰가 팽창 될 때만 인스턴스화됩니다. 그게 내가 널을 얻는 이유. MediaController가 VideoView에 연결되기 전에도 변수를 가져 오려고했습니다.

다음과 같은 접근 방식을 따르고 작동했습니다. 프로덕션 환경에서는 모범 사례가 아니지만 아래 코드 조각이 저에게 효과적이었습니다.

@Override 
protected void onResume() { 
    new Handler().postDelayed(new Runnable() { 

     @Override 
     public void run() { 
      ImageButton button; 
      try { 
       button = (ImageButton) forwardButton.get(controller); 

       if (null == button) Toast.makeText(MainActivity.this, "Button is null", 
       Toast.LENGTH_LONG).show(); 
       else button.setVisibility(View.INVISIBLE); 
      } catch (IllegalArgumentException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } catch (IllegalAccessException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 

     } 
    }, 50); 
    super.onResume(); 
} 
+0

합니까'getDecraledField()'반환 성공적으로 OnResume의 지연 null 이외의 값으로 실행 가능한을 게시 시도하려고? 'MediaController'가 레이아웃을 초기화하기 전에 필드를 가져 오는 중입니까? –

+0

@Singularity 예는 Null이 아닌 값을 반환합니다. –

+0

['onFinishInflate()'] 덮어 쓰기 (http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.1.1_r1/android/widget/MediaController.java# 109),'super.onFinishInflate()'를 호출하면 반사 작업을 할 수 있습니다. –

답변

1

mFfwdButton은보기가 팽창 될 때만 인스턴스화됩니다. 그래서 당신은 null을 얻고 있습니다. 그래서 나는 당신이 그 활동이 사용자에게 보여 질 때까지 그것을 사용할 수 없다고 생각한다. 당신은를 MediaController가 VideoView를 지켜 보면서

에 부착 된도 전에 변수를 얻을

+0

굉장한 남자. 그것은 매력처럼 일했습니다. 1 톤 고마워요. –

관련 문제