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


问题完美解决。

猜你喜欢

转载自aijiawang-126-com.iteye.com/blog/2392432