Android开发之WebView的使用(1)

WebView

目前android市场上的一些应用采用的开发方式大致分为三种:

> Native App - 用原生的Android控件开发出来的应用

> Web App - 使用网页开发的应用

> Hybrid App - 混合式的应用,原生的控件和网页混合开发

Hybrid App中实现的主要技术native组件与Javascript的数据交互以及实现。

概览:

Android WebView在Android平台上是一个特殊的View, 他能用来显示网页,
这个类可以被用来在你的app中仅仅显示一张在线的网页,还可以用来开发浏览器。

WebView内部实现是采用渲染引擎(Webkit)来展示view的内容,提供网页前进后退,网页放大,缩小,搜索,前端开发者可以使用web inspector(Android 4.4系统支持,4.4一下可以采用 http://developer.android.com/guide/webapps/debugging.html )调试HTML,CSS,Javascript等等功能。

在Android 4.3系统及其以下WebView内部采用 Webkit 渲染引擎,在Android 4.4采用 chromium 渲染引擎来渲染View的内容。

WebView的基本使用

  • 创建WebView的实例加入到Activity view tree中
 WebView webview = new WebView(this);  
 setContentView(webview); 
  • 在layout xml中配置WebView
<Webview  
        id="@+id/webview"
        android:layout_width="match_parent"  
        android:layout_height="match_parent" >  
</Webview>  

在代码中:

WebView webView = (WebView)findViewById(R.id.webview)
  • 访问网页

    • 载入互联网网页:
    webview.loadUrl("http://developer.android.com/"); 
    
    • 载入应用中的网页,有一个网页在assets:
    webView.loadUrl("file:///android_asset/page.html"); 
    
  • 添加权限,网络访问权限

<uses-permission android:name="android.permission.INTERNET" />

系统默认会通过手机浏览器打开网页,为了能够直接通过WebView显示网页,则必须设置:

    webview.setWebViewClient(new WebViewClient()
    {
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) 
        {
            view.loadUrl(url);                
            return true;
        }
    });

WebView使用详解

请求加载网页

加载指定的data数据

public void loadData (String data, String mimeType, String encoding)

参数说明:

data 字符串String形式的数据 可以通过base64编码而来,html格式字符串
Content-Type -> text/html; charset=ut-8
mineType data数据的 MIME类型
encoding data数据的编码格式

提示:
1.Javascript有同源限制,同源策略限制了一个源中加载文本或者脚本与来自其他源中的数据交互方式。
避免这种限制可以使用loadDataWithBaseURL()方法。

2.encoding参数制定data参数是否为base64或者 URL 编码,如果data是base64编码那么 encoding必须填写 "base64“。
官方文档:http://developer.android.com/reference/android/webkit/WebView.html

其他方法:

  • public void loadDataWithBaseURL (String baseUrl, String data,
    String mimeType, String encoding, String historyUrl) 使用baseUrl加载base URL的网页内容,baseUrl解决相关url使用Javascript相同源问题。

  • public void loadUrl (String url) 加载制定url的网页内容

  • public void loadUrl (String url, Map<String, String> additionalHttpHeaders) 加载制定url并携带http header数据。

  • public void reload () 重新加载页面

前进后退

  • public void goBack () 返回
  • public void goForward () 前进
  • public void goBackOrForward (int steps) 以当前的index为起始点前进或者后退到历史记录中指定的steps,如果steps为负数则为后退,正数则为前进
  • public boolean canGoForward () 是否可前进
  • public boolean canGoBack () 是否可返回

JavaScript操作

在webview添加对js的支持:

WebSettings setting = webView.getSettings();  
setting.setJavaScriptEnabled(true);//支持js

public void addJavascriptInterface (Object object, String name)
当网页需要和App进行交互时,可以注入Java对象提供给JavaScritp调用. Java对象提供相应的方法供js使用

提示(重要):
问题:在Android 4.2以下使用这个api会涉及到JavaScript安全问题,javascript可以通过反射这个java对象的相关类进行攻击。

解决:可以采用白名单的机制调用这个方法

在Android4.2极其以上系统需要给提供js调用的方法前加入一个注视:@JavaScriptInterface;
在虚拟机当中 Javascript调用Java方法会检测这个anotation,如果方法被标识@JavaScriptInterface则Javascript可以成功调用这个Java方法,否则调用不成功。

网页查找功能

  • public int findAll (String find) 这个API在Android 4.1 就已经被去除, 在Android 4.1极其以上系统使用findAllAsync方法
  • public void findAllAsync (String find) 异步执行查找网页内包含的字符并设置高亮,查找结果会回调.
  • public void findNext (boolean forward) 查找下一个匹配的字符

数据清除

  • public void clearCache (boolean includeDiskFiles) 清除网页访问留下的缓存,由于内核缓存是全局的因此这个方法不仅仅针对webview而是针对整个应用程序.
  • public void clearFormData () 这个api仅仅清除自动完成填充的表单数据,并不会清除WebView存储到本地的数据。
  • public void clearHistory () 清除当前webview访问的历史记录,只会webview访问历史记录里的所有记录除了当前访问记录.
  • public void clearMatches () 清除网页查找的高亮匹配字符
  • public void clearView () 在Android 4.3及其以上系统这个api被丢弃了, 并且这个api大多数情况下会有bug,经常不能清除掉之前的渲染数据。官方建议通过loadUrl("about:blank")来实现这个功能

WebView的状态

  • public void onResume () 激活WebView为活跃状态,能正常执行网页的响应
  • public void onPause () 当页面被失去焦点被切换到后台不可见状态,需要执行onPause动过, onPause动作通知内核暂停所有的动作,比如DOM的解析、plugin的执行、JavaScript执行。并且可以减少不必要的CPU和网络开销,可以达到省电、省流量、省资源的效果。
  • public void pauseTimers () 当应用程序被切换到后台我们使用了webview, 这个方法不仅仅针对当前的webview而是全局的全应用程序的webview,它会暂停所有webview的layout,parsing,javascripttimer。降低CPU功耗。
  • public void resumeTimers () 恢复pauseTimers时的动作。
  • public void destroy () 这个方法必须在webview从view tree中删除之后才能被执行, 这个方法会通知native释放webview占用的所有资源。

WebView 事件回调监听

  • public void setWebChromeClient (WebChromeClient client) 主要通知客户端app加载当前网页的 title,Favicon,progress,javascript dialog等事件,通知客户端处理这些相应的事件。
  • public void setWebViewClient (WebViewClient client) 主要通知客户端app加载当前网页时的各种时机状态,onPageStart,onPageFinish,onReceiveError等事件。

例:

    package com.example.webviewdemo;  
      
    import android.annotation.SuppressLint;  
    import android.app.Activity;  
    import android.content.Context;  
    import android.graphics.Bitmap;  
    import android.os.Message;  
    import android.webkit.WebChromeClient;  
    import android.webkit.WebSettings;  
    import android.webkit.WebView;  
    import android.webkit.WebViewClient;  
      
    public class WebViewBase extends WebView {  
        private static final String DEFAULT_URL = "http://www.baidu.com/";  
        private Activity mActivity;  
        public WebViewBase(Context context) {  
            super(context);  
            mActivity = (Activity) context;  
            init(context);  
        }  
          
        @SuppressLint("SetJavaScriptEnabled")  
        private void init(Context context) {  
            WebSettings webSettings = this.getSettings();  
            webSettings.setJavaScriptEnabled(true);  
            webSettings.setSupportZoom(true);  
            //webSettings.setUseWideViewPort(true);  
            this.setWebViewClient(mWebViewClientBase);  
            this.setWebChromeClient(mWebChromeClientBase);  
            this.loadUrl(DEFAULT_URL);  
            this.onResume();  
        }  
          
        private WebViewClientBase mWebViewClientBase = new WebViewClientBase();  
          
        private class WebViewClientBase extends WebViewClient {  
      
            @Override  
            public boolean shouldOverrideUrlLoading(WebView view, String url) {  
                // TODO Auto-generated method stub  
                return super.shouldOverrideUrlLoading(view, url);  
            }  
      
            @Override  
            public void onPageStarted(WebView view, String url, Bitmap favicon) {  
                // TODO Auto-generated method stub  
                super.onPageStarted(view, url, favicon);  
            }  
      
            @Override  
            public void onPageFinished(WebView view, String url) {  
                // TODO Auto-generated method stub  
                super.onPageFinished(view, url);  
            }  
      
            @Override  
            public void onReceivedError(WebView view, int errorCode,  
                    String description, String failingUrl) {  
                // TODO Auto-generated method stub  
                super.onReceivedError(view, errorCode, description, failingUrl);  
            }  
      
            @Override  
            public void doUpdateVisitedHistory(WebView view, String url,  
                    boolean isReload) {  
                // TODO Auto-generated method stub  
                super.doUpdateVisitedHistory(view, url, isReload);  
            }  
        }  
          
        private WebChromeClientBase mWebChromeClientBase = new WebChromeClientBase();  
          
        private class WebChromeClientBase extends WebChromeClient {  
      
            @Override  
            public void onProgressChanged(WebView view, int newProgress) {  
                mActivity.setProgress(newProgress * 1000);  
            }  
      
            @Override  
            public void onReceivedTitle(WebView view, String title) {  
                // TODO Auto-generated method stub  
                super.onReceivedTitle(view, title);  
            }  
      
            @Override  
            public void onReceivedTouchIconUrl(WebView view, String url,  
                    boolean precomposed) {  
                // TODO Auto-generated method stub  
                super.onReceivedTouchIconUrl(view, url, precomposed);  
            }  
      
            @Override  
            public boolean onCreateWindow(WebView view, boolean isDialog,  
                    boolean isUserGesture, Message resultMsg) {  
                // TODO Auto-generated method stub  
                return super.onCreateWindow(view, isDialog, isUserGesture, resultMsg);  
            }  
              
        }  
    }

Android 5.0Lollipop新API

public static void enableSlowWholeDocumentDraw ()
Android 5.0 Webview默认提供减少内存占用支持,并且智能选择需要绘制的HTML document部门来提供性能。当然开发者可以在自己应用程序需要时关闭这个选项(enableSlowWholeDocumentDraw)。

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

推荐阅读更多精彩内容