• Activity设置style透明后与SurfaceView合用引发的无形命案


    近期搞视频通话,SurfaceView是不可缺少的,因为启动视频要载入一些资源,比較耗时。会有1.2s黑屏的现象,为了改善用户体验,我们须要设置Activity的Theme为透明风格(QQ 也是如此),以下是我截取的日志。QQ和我们启动视频通话界面(Activity)所花费的时间:

    Displayed com.xxx.xxx/.activity.voip.CallVoipVideoActivity: +491ms:接收视频邀请

    Displayed com.xxx.xxxx/.activity.voip.CallVoipVideoActivity: +1s737ms:发起视频邀请(包含载入视频预览)

    Displayed com.tencent.mobileqq/com.tencent.av.ui.AVActivity: +1s977ms :发起视频邀请(QQ载入的资源很多其它,故会略微再慢点,只是区别不大)

    查看后台日志。发现一直在GC,当时我以为内存泄露了。电脑卡的要死,Mat了半天。

    。。


    问题来了,经測试发现,在视频预览出现时,常常界面上的button可见,可是包括SurfaceView的FrameLayout布局处却是透明的,虽然我在主Activity的根布局设置了默认背景,仅仅要你嵌套了SurfaceView而且SurfaceView未载入进内容。就会出现这样的问题。

    主Activity的布局例如以下:

    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/mainLayout"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:background="@drawable/a" >
    
        <include layout="@layout/test1_item" />
    
    </FrameLayout>

    当中,a是默认的背景图片,test1_item.xml是包括SurfaceView的子布局,例如以下:

    <?xml version="1.0" encoding="utf-8"?>
    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    
        <FrameLayout
            android:id="@+id/testFr"
            android:layout_width="match_parent"
            android:layout_height="match_parent" >
    
            <SurfaceView
                android:layout_width="match_parent"
                android:layout_height="match_parent" />
        </FrameLayout>
    
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent" >
    
            <Button
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true"
                android:text="挂断" />
        </RelativeLayout>
    
    </FrameLayout>

    測试发现。在SurfaceView有内容载入进来之前。那部分一直是透明的,无论你根布局有木有设置默认背景。

    关于这个问题的解释,我们须要去了解下SurfaceView及Activity的原理:可參照:http://www.2cto.com/kf/201303/196117.html(SurfaceView理解)。

    http://blog.csdn.net/qinjuning/article/details/7226787(关于Activity的原理)。

    当中注意下两段话:

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

    2、DecorView类 :该类是PhoneWindow类的内部类说明: 该类是一个FrameLayout的子类,而且是PhoneWindow的子类,该类就是对普通的FrameLayout进行功能的扩展,更确切点能够说是修饰(Decor的英文全称是Decoration。即“修饰”的意思),比方说加入TitleBar(标题栏),以及TitleBar上的滚动栏等 。

    最重要的一点是,它是全部应用窗体的根View 。



    解决的方法就是动态加入SurfaceView,可是前提是要保证SurfaceView已经有我们所须要的内容;第二个解决的方法能够为SurfaceView设置一个默认的背景,背景的设置能够參照:http://bbs.csdn.net/topics/380141705,我们能够分析到:surfaceview默认是黑色的背景所以使用SurfaceView要特别注意这个问题(你所要显示的可能会被覆盖等现象),下边这三行代码是设置surfaceView控件背景透明:

    this.setZOrderOnTop(true);
    //this.setEGLConfigChooser(8, 8, 8, 8, 16, 0);
    this.getHolder().setFormat(PixelFormat.TRANSLUCENT);
     只是中间那句是OpenGl的。视情况使用,无用可凝视掉了,也能实现了透明,可是GLSurfaceView就必须使用

    注意:SurfaceView加入背景后,要掉用setZOrderOnTop(true)这种方法才干把我们的内容画上,要不然我们所绘制的内容就在背景后面了,被背景覆盖。另外,在ViewPage中用到SurfaceView时,它所取到的画布是整个程序的画布,也就是在某个Activity里调用ViewPage时,ViewPage里包括SurfaceView,当ViewPage显示此SurfaceView就切换到别的Activity。那么SurfaceView所画的图会覆盖该Activity的界面。


    哥们发现我的程序上述两个方法都没办法解决,仅仅能设置默认背景了。就是你启动的时候的背景,在style文件里改动:

    //黑屏问题
    <style name="activityVoipVideoTransparentTheme" parent="@android:style/Theme.Black.NoTitleBar">
            <item name="android:windowBackground">@drawable/voip_video_default_big</item>
            <item name="android:windowContentOverlay">@null</item>
        </style>
    这样也能达到效果啦。只是假设要不黑屏,实质上还是要分析下究竟是哪里的问题导致主线程较耗时,有些东西能够适当延后载入


  • 相关阅读:
    微信录音文件上传到服务器以及amr转化成MP3格式,linux上转换简单方法
    浅谈java中==与equals的区别
    到处是坑的微信公众号支付开发(java)
    接口测试,获取登录后的cookies
    robotframework中的try exception。断言失败后,后面语句能继续执行
    变量的值与判断的结果有关,使用Set Variable If
    有时候提示框弹出,导致后续动作失效
    element not interactable,这种提示表示元素当前在页面上不可见
    robotframework上面的python脚本语法出错,在错误详情中可看,如果还不明白,可以放到pycharm中去分析,更详细
    IndentationError 这个错误是缩进的问题
  • 原文地址:https://www.cnblogs.com/jzssuanfa/p/7278318.html
Copyright © 2020-2023  润新知