一、 问题描述
打开H5页面,点击分屏,调整分屏高度,页面出现了白屏
二、 问题定位
先看看分屏操作,activity的生命周期怎么走
很明显,activity销毁又重新创建了
那按道理,activity重新创建, webView的数据又还在, webView重新创建,url、header都不为空,正常应该是能展示出来,可界面就一直是白屏
三、解决方案1
既然是activity重新创建导致的,那可以考虑在manifest 设置对应的配置, 以达到分屏不重走生命周期。
上代码
<activity
android:name=".uicomponent.WebViewActivity"
android:configChanges="orientation|screenSize|keyboardHidden|screenLayout|smallestScreenSize"
android:hardwareAccelerated="true"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar" />
添加了screenLayout|smallestScreenSize配置后,分屏调整屏幕大小,activity确实不销毁重新创建了,当然H5页面也显示正常。
介绍一下这两个属性
在 Android 中,Activity 的配置 screenLayout 表示 Activity 支持的屏幕布局类型,smallestScreenSize 表示 Activity 所支持的最小屏幕尺寸。
- screenLayout 属性
screenLayout 属性表示 Activity 支持的屏幕布局类型。在 Manifest 文件中,可以通过 android:configChanges 属性的 screenLayout 值来指定需要保持不变的屏幕布局类型。在屏幕大小发生变化时,保持 screenLayout 不变可以避免 Activity 的销毁和重建 - smallestScreenSize 属性
smallestScreenSize 属性表示 Activity 支持的最小屏幕尺寸。在 Manifest 文件中,可以通过 android:configChanges 属性的 smallestScreenSize 值来指定需要保持不变的屏幕尺寸类型。在屏幕大小发生变化时,保持 smallestScreenSize 不变可以避免 Activity 的销毁和重建。
风险考虑
分屏操作的用户是少量的, 这两个属性可能会不会影响到正常的业务,例如登录交易支付等重要的业务,如果要这么改则需要测试同学测试的全面, 并且这两个属性是在mainfest配置的,不好做降级处理。
四、问题深究
webView重新创建,url、header都不为空,为啥acticity重新创建后会出现白屏呢?
看看webView是怎么创建的
pullRefreshView?.addView(
webView,
LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
)
直接通过add的方式添加webView的,难道重新创建,pullRefreshView和webView的大小变为0?
打印一下, 大小并非为0,而是MATCH_PARENT
Activity >>> web.w = -1 web.h = -1
Activity >>> lay.w = -1 lay.h = -1
那看看布局吧, 直接add在SmartRefreshLayout上? 这深究下去就是布局的嵌套问题了。。。
<com.sui.widget.refresh.layout.SmartRefreshLayout
android:id="@+id/refreshLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--webView改成addView添加-->
</com.sui.widget.refresh.layout.SmartRefreshLayout>
先解决问题先
五、解决方案2
添加FrameLayout布局,把webView添加到FrameLayout上
<com.sui.widget.refresh.layout.SmartRefreshLayout
android:id="@+id/refreshLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/web_container"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<!--webView改成addView添加-->
</com.sui.widget.refresh.layout.SmartRefreshLayout>
运行一下 ~
OK, 问题也解决了
结论: 这样处理,比起方案1,对应个业务来说风险更低
六、后话
为什么使用addView的方式?直接在布局上写上webView就可以了,例如
<com.sui.widget.refresh.layout.SmartRefreshLayout
android:id="@+id/refreshLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<WebView
android:id="@+id/web"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</com.sui.widget.refresh.layout.SmartRefreshLayout>
确实这样也是可以的,还能减少层级嵌套, 翻了下git记录,最初也是这么处理的
后面为啥改了呢?
原因上打开WebView的速度的优化,提前渲染webView, 对webView的复用, 对于特殊页面确实效果也明显
好了,就这样吧。。。。
七、写在最后
此文章为个人开发时记录,有时时间有限,无法深入研究,若看到此文章后有其他见解或解决方式,欢迎留言交流👇👇👇
————————————————
版权声明:转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_44158429/article/details/132162326