`

SurfaceView透到桌面导致画面闪烁

阅读更多
这两天遇到这样的bug:播放视频的时候,会先闪现一下桌面再显示视频。

第一我想到的是activity 的window background设置为了null,找到对应的activity (/packages/apps/Gallery2/src/com/android/gallery3d/app/MovieActivity.java)将
// We set the background in the theme to have the launching animation.
     // But for the performance (and battery), we remove the background here.
      win.setBackgroundDrawable(null); win.setBackgroundDrawable()设置为一张图片。运行问题仍存在。

接着我看了播放视频MovieActivity的布局文件:
RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/movie_view_root"
       android:background="@android:color/black"
       android:layout_width="match_parent"
      android:layout_height="match_parent">
   //这里使用了自定义的surfaceview来播放视频
</RelativeLayout>
这个布局文件里也设置了黑色的背景。接着我也修改了activity的主题,还是没有作业。按道理不可能看到桌面才对!可是事实是看到了!

最后定位到了SurfaceView,最后在网上搜索了到SurfaceView的原理:
http://blog.csdn.net/luoshengyang/article/details/8661317/

注意,用来描述SurfaceView的Layer或者LayerBuffer的Z轴位置是小于用来其宿主Activity窗口的Layer的Z轴位置的,但是前者会在后者的上面挖一个“洞”出来,以便它的UI可以对用户可见。实际上,SurfaceView在其宿主Activity窗口上所挖的“洞”只不过是在其宿主Activity窗口上设置了一块透明区域。

接着我按照网上的方法,修改
setZOrderOnTop(true);   
mHolder.setFormat(PixelFormat.TRANSPARENT);//设置背景透明

但这种做法会使得surfaceView属于view树的顶层,导致将其他的播放按钮挡住了。
最后再同事的提醒下参考了/packages/apps/Gallery2/src/com/android/gallery3d/ui/GLRootView.java这里的做法。
增加一层view来遮住surfaceview.

GLSurfaceView也是继承Surfaceview,所以也同样有透明到桌面的问题。

       // We put a black cover View in front of the SurfaceView and hide it
        // after the first draw. This prevents the SurfaceView being transparent
       // before the first draw.
       if (mFirstDraw) {
          mFirstDraw = false;
            post(new Runnable() {
                  @Override
                    public void run() {
                      View root = getRootView();
                       View cover = root.findViewById(R.id.gl_root_cover);
                       cover.setVisibility(GONE);
                    }
                });
       }


所以我也在
RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/movie_view_root"
       android:background="@android:color/black"
       android:layout_width="match_parent"
      android:layout_height="match_parent">
   //这里使用了自定义的surfaceview来播放视频
  //增加一层cover
<View android:id="@+id/root_cover"
           android:layout_width="match_parent"
            android:layout_height="match_parent"
           android:background="@android:color/black"/>
</RelativeLayout>
当视频prepare完成之后将这个cover隐藏起来。在MediaPlayer.OnPreparedListener回调函数里增加
 if (mFirstDraw) {
          mFirstDraw = false;
            post(new Runnable() {
                  @Override
                    public void run() {
                      View root = getRootView();
                       View cover = root.findViewById(R.id.gl_root_cover);
                       cover.setVisibility(GONE);
                    }
                });
       }


问题完美解决。
分享到:
评论

相关推荐

    解决SurfaceView设置透明造成覆盖其他组件的替代方案

    在Android开发中,SurfaceView是一种特殊的视图,用于显示高性能的图形内容,如视频播放、游戏画面等。然而,当开发者尝试将SurfaceView设置为透明时,可能会遇到一个常见的问题:透明的SurfaceView会覆盖其下方的...

    DrawImage SurfaceView 多层绘制透明图

    `DrawImage`则涉及到在`SurfaceView`上进行图像绘制的操作,而透明图层则涉及到颜色 alpha 值的使用,允许图像部分或全部透明,以便在多层图像叠加时产生叠加效果。 首先,我们需要理解`SurfaceView`的基本概念。它...

    Android SurfaceView 实现实时显示摄像头视频

    1. **创建SurfaceView**: 在布局文件中添加`SurfaceView`元素,或者在代码中动态创建并添加到布局中。 ```xml &lt;SurfaceView android:id="@+id/surface_view" android:layout_width="match_parent" android:...

    在surfaceview上放置控件

    3. **处理触摸事件**:由于SurfaceView可能会截获所有的触摸事件,导致上方的FrameLayout无法接收到触摸事件,因此你需要在SurfaceView的`onTouchEvent()`方法中转发事件到FrameLayout。这可以通过调用`...

    SurfaceView

    SurfaceView内部实现了双缓冲机制,避免了屏幕闪烁问题。在绘图时,先在后台缓冲区完成,然后一次性将整个画面刷新到前台,保证了显示的连贯性。 4. **线程管理**: SurfaceView自带一个用于绘制的子线程,称为...

    Android SurfaceView添加组件view不被组件覆盖-IT计算机-毕业设计.zip

    通常,如果直接将View添加到SurfaceView上,由于SurfaceView的特性,这些View会被绘制在SurfaceView之下。为了解决这个问题,开发者可能采用了以下几种方法: 1. **使用FrameLayout或RelativeLayout**:将...

    SurfaceView放大和缩小

    标题“SurfaceView放大和缩小”涉及到的是如何在Android应用中实现对SurfaceView内的视频画面进行局部放大和缩小的功能。这个功能通常是为了提供用户更细致的观察体验,或者增强交互性。 首先,我们要理解...

    android surface 背景透明,图片拖拉

    5. **Canvas与绘图**:SurfaceView的`onDraw()`方法中,我们可以获取到一个Canvas对象,通过这个对象我们可以绘制Bitmap以及其他图形元素。在拖动操作中,我们需要清除Canvas(`canvas.drawColor()`),然后根据新的...

    surfaceview 多点触控移动放大缩小

    SurfaceView不同于普通的View,它拥有自己的Surface对象,可以独立于UI线程进行渲染,避免了因为复杂的图形计算导致主线程阻塞,提升了性能。它通常用于需要连续、高性能渲染的应用,如游戏、视频播放等。 2. 触摸...

    解决Android SurfaceView绘制触摸轨迹闪烁问题的方法

    SurfaceView有两层缓冲,当用户在屏幕上的触控动作导致频繁绘制时,新旧两帧画面交替显示,如果更新速度不均匀,就可能导致肉眼可见的闪烁现象。此外,如果在处理触摸事件时没有正确地管理路径,也可能造成闪烁或...

    surfaceview

    SurfaceView的核心特性是它拥有自己的独立线程,这个线程称为"SurfaceHolder"回调线程,它与主线程分离,使得UI更新和图形绘制可以在不同的线程中进行,避免了因频繁更新导致的UI阻塞。这在处理密集型图形计算时尤其...

    SurfaceView中添加Animation

    如果同时有多个线程修改Surface的内容,可能会导致画面闪烁或异常。可以使用SurfaceHolder的`lockCanvas()`和`unlockCanvasAndPost()`方法来确保在同一时间只有一个线程在绘制。 5. **优化性能** 为了保证游戏或...

    Android中SurfaceView截屏

    然而,由于其特殊的性质,直接通过常规方式截取`SurfaceView`中的画面可能会遇到困难。本文将详细介绍如何在Android中实现`SurfaceView`的截屏功能。 首先,了解`SurfaceView`的基本原理。`SurfaceView`创建了一个...

    android SurfaceView 使用示例 why SurfaceView上 不可以用控件的轻微解释

    在Android开发中,SurfaceView是一种特殊的视图组件,它提供了与硬件图形渲染引擎直接交互的能力,常用于处理高性能、低延迟的视频或者游戏画面。SurfaceView的底层机制使其能够独立于UI主线程进行渲染,避免了频繁...

    Android中SurfaceView的使用

    1. **双缓冲机制**:SurfaceView内部使用了双缓冲技术,一帧数据在后台缓冲区完成渲染后,再切换到前台显示,这样可以减少画面闪烁,提高用户体验。 2. **独立的渲染线程**:SurfaceView拥有自己的SurfaceHolder,...

    surfaceview 支持横竖屏切换 视屏适配屏幕

    当设备旋转时,Android系统会销毁当前的Activity并重新创建,这可能导致SurfaceView的销毁和重建。因此,开发者需要在Activity的生命周期方法中妥善管理SurfaceView,确保视频播放不会因屏幕方向改变而中断。通常,...

    多个surfaceview的切换有问题

    当切换SurfaceView时,如果不正确地处理SurfaceHolder的状态,可能导致画面卡顿或数据丢失。确保在不再使用SurfaceView时调用`SurfaceHolder.removeCallback()`,并添加新的SurfaceView时重新设置回调。 2. **渲染...

Global site tag (gtag.js) - Google Analytics