Android VideoView setVideoURI 阻塞UI线程

7
在Android中,VideoView的setVideoURI方法似乎会阻塞UI线程。一旦调用此方法,即使在快速设备上,UI也会变得卡顿。有没有办法提高性能呢?我在这里找到了唯一一个相关主题的帖子:
https://groups.google.com/forum/#!topic/android-developers/eAAEAEDcksM
但是它很古老,并没有令人满意的答案。

setVideoURI似乎会在内部调用mMediaPlayer.prepareAsync(),因此它应该不会阻塞并立即返回,但实际上并非如此。因此,从VideoView切换到MediaPlayer也没有帮助。 - Micky
你尝试过将你的代码放在一个异步任务中吗? - user2528167
3
每次调用 setVideoUri() 都会发生这种情况吗?还是只有从第二次开始才会出现? - matiash
我正在使用AsyncTask,但它没有任何效果。我不知道是否因为第一次调用时还有其他事情在进行,所以可能是这个原因。但我正在相当快地进行多次后续调用,所以可能与此有关?我认为随着每次调用的增加,情况越来越糟糕,然后UI会被阻塞一段时间,然后又变得好起来。 - Micky
Hye Kim,你能解决这个问题吗? - nilkash
嗨,不好意思我无法解决它。这似乎是SDK的问题。 - Micky
4个回答

2
我所做的是将setVideoUri()方法放入一个带有looper的handler中,即:
new Handler(Looper.myLooper()).post(new Runnable(){
    @Override
    public void run(){
        videoview.setVideoUri("uri");
    }
});

这将在主UI线程之外运行代码,但保持在一个looper中,以便可以执行代码而不会引发异常。


这似乎没有帮助。它允许UI线程进一步进行,因此具有工作外观,但是一旦处理程序运行,UI线程将被阻塞,而媒体正在解码。 - MrK

2

VideoView.setVideoURI()会为媒体播放启动一个新线程,但是媒体解码部分会导致额外的延迟。唯一可能适用于您的解决方案是使用一些NDK hack,但对我来说不值得。


实际上,我发现当网络连接缓慢时,阻塞情况变得更加严重。这表明解码不是延迟的唯一来源。或者说,是否有任何解释可以说明为什么在网络状况不佳的情况下,媒体解码会出现更多的阻塞? - Micky
我真的不确定,这取决于您在源代码中正在做什么,但如果连接速度慢,则解码器需要执行更多操作,因为它会重复计算和执行通常不需要执行的操作,因为在等待数据包时缓冲区被清除。 - Stanojevic Dalibor

0

我发现VideoView没有阻塞UI线程。实际上,“android.media.VOLUME_CHANGED_ACTION”的接收器会阻塞UI线程。

我的问题代码:

public void setVolume(int volume) {
    try {
        audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, volume, 0);
        ivVoice.setTag(volume != 0);
        updateVoiceImage();
    } catch (Exception e) {
        e.printStackTrace();
    }

}

从音量接收器调用了setVolume函数,在播放5秒的mp4时已经被调用了1000多次。

audioManager.setStreamVolume在主线程中执行时间太长。

解决方案代码:

public void setVolume(int volume) {
    try {
        //if volume not changed , do nothing.
        if(volume != lastVolume){
            audioManager.setStreamVolume(AudioManager.STREAM_MUSIC,volume,0);
            ivVoice.setTag(volume != 0);
            updateVoiceImage();
            lastVolume = volume;
        }
    } catch (Exception e) {
        e.printStackTrace();
    }

}

所以,请检查您的音量接收器。也许它可以帮助您。


-1
VideoView myVideoView = (VideoView)findViewById(R.id.myvideoview);
myVideoView.setVideoURI(Uri.parse(url));
myVideoView.setMediaController(new MediaController(this));
myVideoView.requestFocus();
myVideoView.start();

我使用了这段代码,也许它可以帮到你。

1
那样会怎么帮助我?我已经在使用setVideoURI调用,这就是我的性能问题的原因。 - Micky

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接