I've got a simple activity which plays video through VideoView
public class AVideo extends Activity {
private VideoView mVideoView;
private MediaController mc;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.a_video);
Bundle extras = getIntent().getExtras();
Uri path = Uri.parse(extras.getString("videoURI"));
mVideoView = (VideoView) findViewById(R.id.video);
mVideoView.setVideoURI(path);
mc = new MediaController(this);
mVideoView.setMediaController(mc);
}
@Override
protected void onResume() {
super.onResume();
mVideoView.start();
mc.show();
}
}
In some cases when user pushes back button, on this activity, before video starts playing, he's got ANR. Here's my traces:
DALVIK THREADS:
"main" prio=5 tid=3 NATIVE
| group="main" sCount=1 dsCount=0 s=N obj=0x4001b268 self=0xbd00
| sysTid=423 nice=0 sched=0/0 cgrp=default handle=-1344001384
at android.media.MediaPlayer._reset(Native Method)
at android.media.MediaPlayer.reset(MediaPlayer.java:1028)
at android.widget.VideoView.release(VideoView.java:476)
at android.widget.VideoView.access$2100(VideoView.java:49)
at android.widget.VideoView$6.surfaceDestroyed(VideoView.java:467)
at android.view.SurfaceView.reportSurfaceDestroyed(SurfaceView.java:488)
at android.view.SurfaceView.updateWindow(SurfaceView.java:413)
at android.view.SurfaceView.onWindowVisibilityChanged(SurfaceView.java:189)
at android.view.View.dispatchWindowVisibilityChanged(View.java:3782)
at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:692)
at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:692)
at android.view.ViewGroup.dispatchWindowVisibilityChanged(ViewGroup.java:692)
at android.view.ViewRoot.performTraversals(ViewRoot.java:706)
at android.view.ViewRoot.handleMessage(ViewRoot.java:1633)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:4363)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:521)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
at dalvik.system.NativeStart.main(Native Method)
Also logcat shows this:
07-01 15:11:40.408: WARN/libutils.threads(2967): Thread (this=0x22818): don't call
waitForExit() from this Thread object's thread. It's a guaranteed deadlock!
I find this question and this bug, but there are no solution.
If you are getting the ANR message, means that your applicaction is insufficiently responsive for a period of time, use runOnUiThread to run the specified action on the UI thread or Asynctask
public class AVideo extends Activity {
private VideoView mVideoView;
private MediaController mc;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.a_video);
Bundle extras = getIntent().getExtras();
Uri path = Uri.parse(extras.getString("videoURI"));
mVideoView = (VideoView) findViewById(R.id.video);
runOnUiThread(new Runnable() {
@Override
public void run() {
mVideoView.setVideoURI(path);
}
});
mc = new MediaController(this);
mVideoView.setMediaController(mc);
}
@Override
protected void onResume() {
super.onResume();
mVideoView.start();
mc.show();
}
}
Try implementing setOnPreparedListener to start the video.
mVideoView.setOnCompletionListener(new OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
Log.i("VIDEO", "onCompletion");
}
});
mVideoView.setOnPreparedListener(new OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
Log.i("VIDEO", "onPrepared");
if(mVideoView.canSeekForward()) mVideoView.seekTo(mVideoView.getDuration()/5);
mVideoView.start();
}
});
mVideoView.setKeepScreenOn(true);
One technique that prevents the Android system from concluding a code that has been responsive for a long period of time is to create a child thread. Within the child thread, most of the actual workings of the codes can be placed, so that the main thread runs with minimal periods of unresponsive times.
public class AVideo extends Activity {
private VideoView mVideoView;
private MediaController mc;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.a_video);
Bundle extras = getIntent().getExtras();
Uri path = Uri.parse(extras.getString("videoURI"));
mVideoView = (VideoView) findViewById(R.id.video);
mVideoView.setVideoURI(path);
mc = new MediaController(this);
mVideoView.setMediaController(mc);
}
@Override
protected void onResume() {
super.onResume();
mVideoView.start();
mc.show();
}
}
来源:https://stackoverflow.com/questions/6547735/android-anr-in-mediaplayer-reset