WebView问题集及优化,webview 漏洞,Webview网页秒开

> 安卓Webview网页秒开策略探索- https://juejin.im/post/5d2605f8f265da1bc23fa07c
-- 网页加载缓慢,白屏,使用卡顿。
webview是怎么加载网页的呢?
webview初始化->DOM下载→DOM解析→CSS请求+下载→CSS解析→渲染→绘制→合成

几个大厂的思路,目的:网页秒开,策略:
- 针对客户端
 1.预创建(application onCreate 时)webview
  1.1预创建的同时加载带有css/js的html文本
 2.webview复用池
 3.webview setting的设置
 4.预取网页并缓存,预先获取html并缓存本地,需要是从缓存中加载即可
 5.资源拦截并行加载,内核初始化和资源加载同时进行。
- 针对服务端
 1.直出网页的拼装,服务端时获取网页的全部内容,客户端获取后直接加载
 2.客户端本地html资源的版本控制
- 针对网页前端
 1.删减不必要的js/css
 2.配合客户端使用VasSonic,只对特定的内容进行页面更新与下载。

> webview性能优化

WebView性能、体验分析与优化- https://blog.csdn.net/meituantech/article/details/80062310

android webview常见问题以及性能优化- http://www.jianshu.com/p/9293505c7f71
-- 总结几种加速WebView加载的方法:
  1、展示webview的activity可以另开一个进程,这样就能和我们app的主进程分开了,即使webview产生了oom崩溃等问题也不会影响到主程序,如何实现呢,其实很简单,在androidmanifest.xml的activity标签里加上android:process="packagename.web"就可以了。运行起来就会发现多了一个进程,哈哈。
  2、webview的创建也是有技巧的,最好不要在layout.xml中使用webview,可以通过一个viewgroup容器,使用代码动态往容器里addview(webview),这样可以在onDestory()里销毁掉webview及时清理内存,另外需要注意创建webview需要使用applicationContext而不是activity的context,销毁时不再占有activity对象,这个大家应该都知道了,最后离开的时候需要及时销毁webview,onDestory()中应该先从viewgroup中remove掉webview,再调用webview.removeAllViews();webview.destory();
  3.WebViewClient.onPageFinished()。你永远无法确定当WebView调用这个方法的时候,网页内容是否真的加载完毕了。当前正在加载的网页产生跳转的时候这个方法可能会被多次调用,StackOverflow上有比较具体的解释(How to listen for a Webview finishing loading a URL in Android?-https://stackoverflow.com/questions/3149216/how-to-listen-for-a-webview-finishing-loading-a-url), 但其中列举的解决方法并不完美。所以当你的WebView需要加载各种各样的网页并且需要在页面加载完成时采取一些操作的话,可能WebChromeClient.onProgressChanged()比WebViewClient.onPageFinished()都要靠谱一些。
  4.WebView后台耗电问题。当你的程序调用了WebView加载网页,WebView会自己开启一些线程(?),如果你没有正确地将WebView销毁的话,这些残余的线程(?)会一直在后台运行,由此导致你的应用程序耗电量居高不下。对此我采用的处理方式比较偷懒,简单又粗暴(不建议),即在Activity.onDestroy()中直接调用System.exit(0),使得应用程序完全被移出虚拟机,这样就不会有任何问题了。
  5.切换WebView闪屏问题。如果你需要在同一个ViewGroup中来回切换不同的WebView(包含了不同的网页内容)的话,你就会发现闪屏是不可避免的。这应该是Android硬件加速的Bug,如果关闭硬件加速这种情况会好很多,但无法获得很好的浏览体验,你会感觉网页滑动的时候一卡一卡的,不跟手。
  6.数据积累问题。开启缓存什么的有利于网页的浏览体验,但你会发现即使是清除了必要的内容,比如Cache、Cookie、Form Data、History、Password等等东西,你的应用程序所占用的存储空间还是会越来越大,到最后只好手动到系统设置的应用信息界面里清除数据了
  7.滚动条问题。Android System WebView的横向滚动条真是好粗的有木有...
  8.在某些手机上,Webview有视频时,activity销毁后,视频资源没有被销毁,甚至还能听到在后台播放。即便是像刚才那样各种销毁webview也无济于事,解决办法:在onDestory之前修改url为空地址。是不是很坑?
  9、提高渲染的优先级,webView.getSettings().setRenderPriority(RenderPriority.HIGH);
 10、使用webView.getSettings().setBlockNetworkImage,把图片加载放在最后来加载渲染。参照示例1.
 11、使用硬件加速,该功能在Android 3.0 (API level 11)才加入。

> Android WebView常见问题集,如WebView中上传照片或文件,拦截JS
Android WebView常见问题及解决方案汇总: http://blog.csdn.net/t12x3456/article/details/13769731/
那些年在WebView上踩过的坑- http://blog.csdn.net/u012124438/article/details/53401663
WebView适配问题- http://blog.csdn.net/a345017062/article/category/1359585
完美解决WebView与上层父元素的TouchMove事件冲突- http://blog.csdn.NET/daeees/article/details/39693231
Android 软键盘盖住输入框的问题-- http://blog.csdn.net/chengyingzhilian/article/details/7975277

【Android Web】腾讯X5浏览器的集成与常见问题- https://blog.csdn.net/qq_21138819/article/details/81278865
WebView 选择相册图片踩坑- https://www.jianshu.com/p/ddf772d51912

-- Android WebView中上传照片或文件
Android开发深入理解WebChromeClient之onShowFileChooser或openFileChooser使用说明- http://teachcourse.cn/2224.html#
Android-AdvancedWebView- https://github.com/delight-im/Android-AdvancedWebView/blob/ecff154ef390a0dbdb5337bd5dea2055205c104f/Source/src/im/delight/android/webview/AdvancedWebView.java#L1011
Android WebView支持Input type=file文件上传- http://blog.csdn.net/muzhengjun/article/details/51954580
Android笔记:Webview 支持 input type=file选择上传图片- http://glblong.blog.51cto.com/3058613/1726034/

-- webView.setJavaScriptEnabled(true),可能会影响Activity的生命周期,在魅族手机上出现,可能导致立即执行Activity的OnPause()生命周期。

-- WebView本身是一个AbsoluteLayout,绘制时,会把Canvas传入本地方法,由JNI调用把浏览器的UI绘制在Canvas上面。当用户聚焦一个输入框时,会生成一个TextView,并把它加入AbsoluteLayout中去。绘制流程变成先绘制浏览器,再绘制TextView,浏览器当中的输入框的样式大小会与TextView在用户每次对页面进行缩放时保持一致。在Android2.0/2.1两个平台上,因为TextView中文本的高度超过了边框调试,导致TextView中的文本只能显示出三分之二来,就出现了这个问题。解决方案就是扩大TextView的文本框。Android1.6及以前的版本,还有最新的2.2这个BUG都被官方解决了。

-- TTS Error: leaked ServiceConnection android.speech.tts.TextToSpeech ?(leaked ServiceConnection android.speech.tts.TextToSpeech$Connection@4274a9f8 that was originally bound here)
  I got this Leaked Connection when using a WebView in my Fragment. In the onCreateView method I did setJavaScriptEnabled(true), which caused this error, when pressing back on the Activity. To get rid of it, I moved the set to onResume(), and also set it to false in onPause(), then problem disappeared.

-- WebView.destroy() called while still attached 解决方法
解决方法如下:
@Override
public void onDestroy() {
        if (webView != null) {
            ViewGroup parent = (ViewGroup) webView.getParent();
            if (parent != null) {
                parent.removeView(webView);
            }
            webView.removeAllViews();
            webView.destroy();
        }
        super.onDestroy();
    }
}

@Override
protected void onDestroy() {
      super.onDestroy();

      if (webView != null) {
         webView.clearHistory();
         webView.clearCache(true);
//       webView.loadUrl("about:blank"); // clearView() should be changed to loadUrl("about:blank"), since clearView() is deprecated now
         webView.freeMemory();
         webView.pauseTimers();

         ViewGroup parent = (ViewGroup) webView.getParent();
         if (parent != null) {
            parent.removeView(webView);
         }
         webView.removeAllViews();
         webView.destroy();
         webView = null; // Note that mWebView.destroy() and mWebView = null do the exact same thing
      }
//    webView.removeAllViews();
//    webView.destroy();
   }

mWebView.stopLoading();//再次打开页面时,若界面没有消亡,会导致进度条不显示并且界面崩溃
在activity的ondestory的时候需要做一下操作
if (mWebView != null) {
            mWebView.stopLoading();//再次打开页面时,若界面没有消亡,会导致进度条不显示并且界面崩溃WebView.stopLoading();
            mWebView.onPause();
            mWebView.clearCache(true)
            mWebView.clearHistory();
            mWebView.removeAllViews();
            mWebView.destroyDrawingCache();
            ViewGroup parent = (ViewGroup) mWebView.getParent();
            if (parent != null) {
                parent.removeView(mWebView);
            }
            mWebView.removeAllViews();
            mWebView.destroy();//这句由于有些在其他线程还没有结束,会导致空指针异常导致没办法使用
            mWebView = null;
        }

-- WebView拦截JS
Android中使用WebView与JS交互全解析- http://blog.csdn.net/u012124438/article/details/53371102

-- Webview加载不了https请求中的http图片
  公司之前用http被劫持了,WebView打开的网页里面有小广告,于是把请求链接改成了https,但是我们的图片服务器还是http的。这一改,对于5.0以下的没有影响,但是由于5.0是默认不支持mixed content的,即不支持同时加载https和http混合模式。解决Webview加载不了https请求中的http图片:
H5页面有混合http和https的链接,5.0以上系统不支持混合模式,需要通过配置来开启
//5.0及以上webview不支持http和https混合模式 需要通过配置来开启混合模式;允许混合内容 解决部分手机 加载不出https请求里面的http下的图片
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
   settings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
}

 Https和http混合在一个网页中
Android 7.0系统webview 显示https页面空白处理- http://blog.csdn.net/li_huorong/article/details/60469607
android webview 访问https页面 SslError 处理- http://blog.csdn.net/aptentity/article/details/71566437
Android端支持HTTP和HTTPS- http://blog.csdn.net/boweijie/article/details/40301911
Android WebView 无法加载Https(或加载错误)- http://m.blog.csdn.net/zhangwenshuan/article/details/55513869
android 用webview加载网页(https和http)- http://blog.csdn.net/qq_30740239/article/details/54141106
Android5.0 WebView中Http和Https混合问题- http://www.zhimengzhe.com/Androidkaifa/78017.html

-- H5 img标签图片无法显示的解决方案- http://blog.csdn.net/qq_16559905/article/details/54317034
使用Referer Meta标签控制referer,在H5 的 header加入meta
<meta name="referrer" content="never">
  1、如果页面中包含了如下 meta 标签,所有从当前页面中发起的请求将不会携带 referer:
<meta name="referrer" content="never">
  2、如果页面中包含了如下 meta 标签,则从当前页面中发起的 http请求将只携带 origin 部分(注:根据原文中的语境,我理解这里的 origin 是包含了 schema 和 hostname 的部分 url,不包含 path 等后面的其他 url 部分),而不是完整的 URL :
<meta name="referrer" content="origin">

  注意:在使用本文中所述的 meta 标签的时候,浏览器原有的 referer 策略将被打破,比如从 http 协议的页面跳转到 https 的页面的时候,如果设置了适当的值,也会携带 referer。

-- Android关于WebView控件stoploading方法的正确使用
  Android中使用WebView控件实现链接超时响应,一般都会通过重写WebViewClient类的onPageStarted方法,通过添加timer,达到自定义链接最大时长的目的,但是在timer的run方法体中调用webview的stoploading方法达不到预料中的效果,原因是出在java线程安全机制,java会认为在异步线程中调用修改控件的状态是不安全的。正确的方法应该是使用Hander类。
例如: // 开始加载页面时
public void onPageStarted(WebView view, String url, Bitmap favicon) {
    super.onPageStarted(view, url, favicon);
    final int progressNum = view.getProgress();
    final Handler handler=new Handler();
    timer = new Timer();
    TimerTask tt = new TimerTask() {
        @Override
        public void run() {
            if (progressNum < 100) {
                System.out.println("链接超时");
                handler.post(runnable);
                timer.cancel();
                timer.purge();
            }
        }
    };
    timer.schedule(tt, 30000, 1);//30最大链接时间为30秒
}

Runnable runnable=new Runnable() {
    public void run() {
        webView.stopLoading();//在这里中断连接
    }
}; 

> 修复webview支持file协议导致被微博SDK漏洞利用问题修复
“webView.getSettings().setAllowFileAccess(true);”是关键,而且值一定要是true,主要目的是为了让webview可以使用file协议;如果想要防止漏洞发生,就需要在代码中明确的将webview使用file协议的权限设置为false。activity是被设置成android:exported=”true”。

避免踩坑:易盾安全老司机起底Android九大漏洞,附解决建议- https://blog.51cto.com/13610827/2116789
Android应用漏洞checklist- https://secvul.com/topics/571.html
 程序可被任意调试,AndroidManifest.xml 配置文件中中设置为android:Debugable=”false”。
 程序数据任意备份,AndroidManifest.xml 配置文件中中设置为android:allowBackup=”false”。
 Activity组件暴露,如果组件不需要与其他app共享数据或交互,请将AndroidManifest.xml 配置文件中设置该组件为exported = “False”。如果组件需要与其他app共享数据或交互, 请对组件进行权限控制和参数校验。
 Service组件暴露,如果组件不需要与其他app共享数据或交互,请将AndroidManifest.xml 配置文件中设置该组件为exported = “False”。如果组件需要与其他app共享数据或交互, 请对组件进行权限控制和参数校验。
 ContentProvider组件暴露,如果组件不需要与其他app共享数据或交互,请将AndroidManifest.xml 配置文件中设置该组件为exported = “False”。如果组件需要与其他app共享数据或交互, 请对组件进行权限控制和参数校验。
 BroadcastReceiver组件暴露,如果组件不需要与其他app共享数据或交互,请将AndroidManifest.xml 配置文件中设置该组件为exported = “False”。如果组件需要与其他app共享数据或交互, 请对组件进行权限控制和参数校验。
 Webview存在本地Java接口,建议开发者不要使用addJavascriptInterface,使用注入javascript和第三方协议的替代方案。
 SSL通信服务端检测信任任意证书,自定义SSL x509 TrustManager,重写checkServerTrusted方法,方法内不做任何服务端的证书校验。严格判断服务端和客户端证书校验,对于异常事件禁止return 空或者null。
 隐式意图调用, 风险描述:封装Intent时采用隐式设置,只设定action,未限定具体的接收对象,导致Intent可被其他应用获取并读取其中数据。将隐式调用改为显式调用。
 WebView忽略SSL证书错误,风险描述:WebView调用onReceivedSslError方法时,直接执行handler.proceed()来忽略该证书错误。不要重写onReceivedSslError方法, 或者对于SSL证书错误问题按照业务场景判断,避免造成数据明文传输情况。
 HTTPS关闭主机名验证,风险描述:构造HttpClient时,设置HostnameVerifier时参数使用ALLOW_ALL_HOSTNAME_VERIFIER或空的HostnameVerifier。APP在使用SSL时没有对证书的主机名进行校验,信任任意主机名下的合法的证书,导致加密通信可被还原成明文通信,加密传输遭到破坏。

WebView File域同源策略绕过漏洞浅析- http://www.droidsec.cn/webview-file%E5%9F%9F%E5%90%8C%E6%BA%90%E7%AD%96%E7%95%A5%E7%BB%95%E8%BF%87%E6%BC%8F%E6%B4%9E%E6%B5%85%E6%9E%90/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值