Android开发之WebView(一)配置&小技巧

背景:原生时间紧没时间开发任务量大的任务,而前端又闲着打酱油

方案:原生+webview混合开发

缺点:对于比较复杂的页面,webview在性能上力不从心;且与原生通信频繁也增加了隐藏的工作量

优点:能自带支持动态更新(js),能充分利用人力

一:WebView介绍

webview是一个基于webkit引擎,展示web页面的控件。Android上的webview在低版本和高版本采用了不同的webkit版本内核,Android4.4(19)后直接使用了Chrome内核;WebView控件功能强大,除了具有一般View的属性和设置外,还可以对url请求,页面加载,渲染,页面交互进行强大的处理。一般来说webview可单独使用,也可联合其工具类一起使用

移动应用的主体是webview,主要以网页语言编写,穿插Native功能的Hybrid App开发类型。激活webview为活跃状态,能正常执行网页的响应;当webview 的页面被失去焦点切换到后台不可见状态onPause时,需要通知自己暂停所有的动作,比如DOM的解析,plugin的执行,JavaScript的执行等

二:WebView的作用

1,显示和渲染web页面

2,直接使用本地assets或者网络上的html文件作为布局

3,可和JavaScript进行互相调用

三:WebView的使用方式

1,直接在布局文件里写死

2,动态添加进viewgroup中

注:不管以哪种方式,都必须注意webview的销毁,否则可能会造成内存泄漏最终导致内存溢出crash

四:WebView常用方法及说明

下面是WebView的一些常用的方法列举,一些已经过时的方法未列出

webview.loadUrl("www.baidu.com")  //加载url
webview.loadurl("javascript:jsmethod()")  //可以执行js函数,没有返回值,其中jsmethod是js中定义的函数
webview.evaluateJavascript(String script, ValueCallback<String> resultCallback)  //script同上,有返回值
webview.setWebViewClient(new WebViewClient());   //设置webviewclient,通过重写部分方法可以实现定制化的功能,拦截url,监控资源加载状态等
webview.setWebChromeClient(new WebChromeClient()   //设置WebChromeClient,重写部分方法可以处理js的对话框,网址图标,标题和加载进度等
webview.onPause()  //webview的生命周期方法,可于activity的生命周期绑定调用,通知webkit内核暂停所有的动作,比如DOM的解析,plugin的执行,JavaScript的执行
webview.onResume   //webview的生命周期方法,可于activity的生命周期绑定调用,通知webkit内核恢复所有的动作,比如DOM的解析,plugin的执行,JavaScript的执行
webview.pauseTimers()   //和onPause搭配使用,针对全应用程序的webview,会暂停所有webview的layout,parsing,JavaScriptTimer,可降低CPU功耗,达到省电的目的
webview.resumeTimers()  //和onResume搭配使用,恢复pauseTimers时的所有动作
webview.destroy()   //销毁webview,一般在activity的onDestroy方法中调用,注意调用时需要先在父容器中移除webview,然后再销毁,如:( (ViewGroup) webView.getParent()).removeView(webView);
webview.stopLoading()  //停止当前加载
webview.clearMatches()  //清除网页查找的高亮匹配字符
webview.clearHistory()  //清除当前webview的历史访问记录
webview.clearCache(true)  //清空网页访问留下的缓存数据(内存+磁盘),为false时只清除内存的
webview.loadUrl("about:blank")  //清空当前加载
webview.removeAllViews()  //清空所有子view

五:WebSettings的常用配置方法及说明

下面是WebSettings的一些常用的方法列举,一些已经过时的方法就没有写出来了

WebSettings settings = webView.getSettings();
String ua = settings.getUserAgentString();
// 添加userAgent,方便前端网页判断请求来源
settings.setUserAgentString(ua + "; app/1.0.0");
// 页面中要与JavaScript交互,需要设置为true
settings.setJavaScriptEnabled(true);
// 设置允许JS弹窗
settings.setJavaScriptCanOpenWindowsAutomatically(true);
//保存表单数据
settings.setSaveFormData(true);
//将图片调整到适合webview的大小
settings.setUseWideViewPort(true);
// 缩放至屏幕的大小
settings.setLoadWithOverviewMode(true);
//不支持缩放
settings.setSupportZoom(false);
//设置内置的缩放控件,这个取决于setSupportZoom,如果setSupportZoom设置为false,则此处设置无效
settings.setBuildInZoomControls(true);
//设置可以访问文件,如果此处设置为false,则webview的input标签的type=‘file’将点击无响应
settings.setAllowFileAccess(true);
//支持多窗口
settings.setSupportMultipleWindows(true);
//支持内容重新布局,实战发现此处如果设置为NARROW_COLUMN会导致某些手机显示不能撑满宽度问题
settings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);
//支持自动加载图片
settings.setLoadsImagesAutomatically(true);
//设置编码格式
settings.setDefaultTextEncodingName("utf-8");
//设置默认字体大小
settings.setDefaultFontSize(16);
//特别注意,5.1以上默认禁止了https和http的混用,以下方式是开启
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    settings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
}

六:WebView常见问题

1,引起内存泄露

在使用webview中,不管是写在xml里还是动态生成的,都会不可避免的将当前的context传入webview中,也就是webview持有当前activity的引用。在我们关闭activity的时候,如果此时webview还在加载就会导致activity无法被回收,造成内存泄漏;总结来说,就是由于多个对象的生命周期不一致导致的无法同生同灭

一般不管是动态生成还是xml写死,只要处理好了引用持有问题,就能有效的避免内存泄漏;下面是我尝试的方案,在工具类WebViewUtils.java里封装好,在activity销毁的时候调用

public static void release(WebView webView) {
        if (webView != null) {
            webView.loadDataWithBaseURL(null, "", "text/html", "utf-8", null);
            webView.stopLoading();
            ViewGroup parent = (ViewGroup) webView.getParent();
            if (parent != null) {
                parent.removeView(webView);
            }
            webView.clearHistory();
            webView.removeAllViews();
            webView.destroy();
        }
    }

    @Override
    public void onDestroy() {
        WebViewUtils.release(mWebView);
        super.onDestroy();
    }
2,加载白屏

由于白屏问题的出现的多样性,暂提供多种尝试性方案,大家按需参考

1,清除webview缓存和记录

webview.clearCache(true);
webview.clearHistory();

2,可以设置不启用缓存

websettings.setAppCacheEnabled(false);

3,H5的一些控件标签不支持导致的白屏

websettings.setDomStorageEnabled(true);

4,xml启用软件加速

 <WebView
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:layerType="software"
     android:scrollbars="none" />

5,通过menifest的来配置,在目标webview的activity设置

<activity
      android:name="xxx"
      android:hardwarAccelerated="false" />
3,安全&漏洞问题
  • Android 4.2前远程代码执行漏洞的问题,又称js注入

这个问题也是老生常谈的问题,其原因是因为在API 17(Android 4.2)以前的系统版本,程序没有正确限制使用addJavascriotInterface方法,远程攻击者可通过使用Java Reflection API利用该漏洞执行任意Java对象的方法,可能出现手机被安装木马程序,发送扣费短信,通信录或者短信被窃取,甚至手机被远程控制等安全问题

解决方案:

1,设置minSdkVersion大于等于17,即不能再低于4.2的手机上运行
2,在需要被调用的Java方法上增加注解声明:@JavascriptInterface

  • webview明文存储密码的问题

webview组建默认开启了密码保护功能,会提示用户是否保存密码,当用户选择保存后,用户名和密码会被以明文形式保存到应用数据目录databases/webview.db中。攻击者可能通过root的方式访问该应用的WebView数据库,从而窃取本地明文存储的用户名和密码

解决方案:

调用webview.getSettings().setSavePassword(false);,让webview不再存储密码

  • 有风险的系统隐藏接口问题

根据CVE披露的webview的远程代码执行漏洞信息,Android系统中存在一共三个有远程代码执行漏洞的隐藏接口。分别位于android/webkit/webview中的searchBoxJavaBridge接口,位于android/webkit/AccessibilityInjector的accessibility接口和accessibilityTraversal,调用此三个接口的APP在开启辅助功能选项中第三方服务的Android系统上将面临远程代码执行漏洞

解决方案:

需要显示移除这三个接口

webview.removeJavascriptInterface("xxx");


文章如有错误,烦请指出。此篇文章作为后续深入的基础铺垫,后面会再续写webview的cookie设置和Android的数据交互等,敬请期待!

上一篇:Flutter入门-01-工程创建&目录介绍

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270