Андроид ANR в смене MediaPlayer

У меня есть простая деятельность, которая воспроизводит видео через 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(); } } 

В некоторых случаях, когда пользователь нажимает кнопку «Назад», в этом действии, прежде чем видео начинает играть, у него есть ANR. Вот мои следы:

 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) 

Также logcat показывает это:

 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! 

Я нахожу этот вопрос и эту ошибку , но решения нет.

Solutions Collecting From Web of "Андроид ANR в смене MediaPlayer"

Если вы получаете сообщение ANR, означает, что ваше приложение недостаточно реагирует на определенный период времени, используйте runOnUiThread для запуска указанного действия в потоке пользовательского интерфейса или 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(); } } 

Попробуйте реализовать setOnPreparedListener для запуска видео.

  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); 

Один из методов, который мешает системе Android заключить код, который реагирует на длительный период времени, – создать дочерний поток. В пределах дочернего потока можно выполнить большую часть фактической работы кодов, чтобы основной поток выполнялся с минимальными периодами времени безответственности.

 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(); } }