Android VideoView setVideoURI 阻塞 UI 线程

Posted

技术标签:

【中文标题】Android VideoView setVideoURI 阻塞 UI 线程【英文标题】:Android VideoView setVideoURI blocks UI thread 【发布时间】:2014-07-02 10:42:05 【问题描述】:

android 中 VideoView 的 setVideoURI 方法似乎阻塞了 UI 线程。一旦我调用此方法,用户界面就会变得迟钝,即使在快速设备上也是如此。有没有办法在这里提高性能? 我可以在这里找到与该主题有关的唯一其他线程:https://groups.google.com/forum/#!topic/android-developers/eAAEAEDcksM 但它已经很老了,没有令人满意的答案。

【问题讨论】:

setVideoURI 似乎在内部调用 mMediaPlayer.prepareAsync() ,因此它应该只返回而不会阻塞,但事实并非如此。所以从 VideoView 切换到 MediaPlayer 也无济于事。 您是否尝试将代码放入异步任务中? 每次拨打setVideoUri()时都会出现这种情况吗?还是只从第二次开始? 我正在使用AsyncTask,但它没有任何效果。我不知道它是否第一次发生,因为我第一次调用它时,还有其他事情发生。但是我很快就打了多个后续电话,所以也许与此有关?我认为每次调用都会变得更糟,然后 UI 会阻塞一段时间,然后又会好转。 Hye Kim 你能解决这个问题吗? 【参考方案1】:

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

【讨论】:

其实我体验过,当网速慢时,阻塞会变得更加严重。这将反对解码是延迟的唯一来源。或者有没有解释为什么媒体解码会在连接不良时阻塞更多? 我真的不确定,这取决于你在源中做什么,但如果连接很慢,那么解码器有更多的工作人员要做,因为重复计算和做通常不会的操作因为缓冲区在等待数据包之间被清除【参考方案2】:

我所做的是将 setVideoUri() 方法放入带有循环器的处理程序中,即

new Handler(Looper.myLooper()).post(new Runnable()
    @Override
    public void run()
        videoview.setVideoUri("uri");
    
);

这会在主 UI 线程之外运行代码,但会将其保存在 Looper 中,这样代码就可以在不引发异常的情况下执行

【讨论】:

这似乎没有帮助。它允许 UI 线程进一步前进,因此它看起来可以工作,但是一旦处理程序运行,UI 线程就会在媒体解码时被阻塞【参考方案3】:

我发现 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,播放5s 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();
    


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

【讨论】:

【参考方案4】:
VideoView myVideoView = (VideoView)findViewById(R.id.myvideoview);
myVideoView.setVideoURI(Uri.parse(url));
myVideoView.setMediaController(new MediaController(this));
myVideoView.requestFocus();
myVideoView.start();

我用过这段代码,希望对你有帮助

【讨论】:

这对我有什么帮助?我已经在使用 setVideoURI 调用,这就是我的性能问题的原因

以上是关于Android VideoView setVideoURI 阻塞 UI 线程的主要内容,如果未能解决你的问题,请参考以下文章

Android 7 上的 VideoView 错误

Android开发之使用VideoView播放视频

Android VideoView 在 stopPlayback() 后清除显示

android 修改videoview的宽度和高度

VideoView - Android 活动关闭

如何在 Android Studio 中将一个 VideoView 放在另一个 VideoView 下方?