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();
}
합니까'getDecraledField()'반환 성공적으로 OnResume의 지연 null 이외의 값으로 실행 가능한을 게시 시도하려고? 'MediaController'가 레이아웃을 초기화하기 전에 필드를 가져 오는 중입니까? –
@Singularity 예는 Null이 아닌 값을 반환합니다. –
['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()'를 호출하면 반사 작업을 할 수 있습니다. –