2011-07-01 116 views
18

我有一个简单的活动,其通过VideoViewAndroid的ANR重置

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! 

我发现this questionthis bug,但目前还没有解决方案。

+0

我得到了同样的问题,你有解决它吗? – dreamtale

+0

@dreamtale否:-( – kreker

+0

@dreamtale好吧,我只是用意图启动用户的视频播放器 – kreker

回答

0

阻止Android系统结束长时间响应的代码的一种技术是创建一个子线程。在子线程中,可以放置代码的大部分实际工作,以便主线程以最少的无响应时间运行。

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

} 
1

如果您收到的ANR消息,意味着你的applicaction是一段时间不足以应对,使用runOnUiThread运行UI线程上执行指定动作或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);