安卓webview开发简介

1.WebView的基本使用
(1)创建WebView的实例加入到Activity view tree中

WebView webview = new WebView(this);  
setContentView(webview);  
  • 1

(2)在xml中配置WebView

<Webview 
 android:layout_width="match_parent" 
 android:layout_height="match_parent" >  
</Webview>  
  • 1

(3)访问网页

webview.loadUrl("http://developer.android.com/"); 
  • 1

2.WebView API使用详解
1)请求加载网页部分

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

加载指定的data数据

参数说明:

data 字符串String形式的数据 可以通过base64编码而来

mineType data数据的 MIME类型, e.g. ‘text/html’

encoding data数据的编码格式

Tips:

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) 
  • 1

使用baseUrl加载base URL的网页内容,baseUrl解决相关url使用Javascript相同源问题。

public void loadUrl (String url)  
  • 1

加载制定url的网页内容

public void loadUrl (String url, Map<String, String> additionalHttpHeaders)  
  • 1

加载制定url并携带http header数据。

public void reload ()
  • 1

重新加载页面

Tip(重要)

页面所有资源会重新加载

public void stopLoading () 
  • 1

2) 前进后退

public void goBack () 
  • 1
public void goForward ()  
  • 1
public void goBackOrForward (int steps)  
  • 1

以当前的index为起始点前进或者后退到历史记录中指定的steps, 如果steps为负数则为后退,正数则为前进

public boolean canGoForward ()  
  • 1
public boolean canGoBack ()  
  • 1

3)JavaScript操作

public void addJavascriptInterface (Object object, String name)  
  • 1

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

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

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

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

example:

class JsObject {  
   @JavascriptInterface  
   public String toString() { return "injectedObject"; }  
}  
webView.addJavascriptInterface(new JsObject(), "injectedObject");  
  • 1
public void evaluateJavascript (String script, ValueCallback<String> resultCallback)  
  • 1

这个方法在Android 4.4系统引入,因此只能在Android4.4系统中才能使用,提供在当前页面显示上下文中异步执行javascript代码
Tips(重要)

这个方法必须在UI线程调用,这个函数的回调也会在UI线程执行。

那么在Android4.4一下如何执行javascrit代码呢

可以通过 WebView提供的loadUrl方法:具体格式如下:

webView.loadUrl("javascript:alert(injectedObject.toString())"); 
  • 1

其中javascript: 是执行javascript代码的标识 , 后面是javascript语句。

这里写代码片
  • 1

public void removeJavascriptInterface (String name)
删除addJavascripInterface时对webview注入的java对象. 此方法在不同的Android系统WebView会有问题,会存在失效情况。

4)网页查找功能

public int findAll (String find)  PI在Android 4.1 就已经被去除, 在Android 4.1极其以上系统使用findAllAsync方法
这个API还存在bug 具体请见我的之前一篇博文Android WebView findAll bug

  • 1

public void findAllAsync (String find)

异步执行查找网页内包含的字符并设置高亮,查找结果会回调.
  • 1

public void findNext (boolean forward)

查找下一个匹配的字符
使用example:



public class TestFindListener implements android.webkit.WebView.FindListener {  
    private FindListener mFindListener;      public TestFindListener(FindListener findListener) {  
        mFindListener = findListener;  
    }  

    @Override  
    public void onFindResultReceived(int activeMatchOrdinal, int numberOfMatches,  
            boolean isDoneCounting) {  
        mFindListener.onFindResultReceived(activeMatchOrdinal, numberOfMatches, isDoneCounting);  
    }  
}  

   public void findAllAsync(String searchString) {  
       if (android.os.Build.VERSION_CODES.JELLY_BEAN <= Build.VERSION.SDK_INT)  
           mWebView.findAllAsync(searchString);  
       else {  
           int number = mWebView.findAll(searchString);  
           if (mIKFindListener !=null)  
               mIKFindListener.onFindResultReceived(number);  
           fixedFindAllHighLight(); 


 // 参见我之前一篇博文Android WebView API findAll bug 
       }  
   }  

   mWebView.findNext(forward);  
  • 1

5)数据清除部分

public void clearCache (boolean includeDiskFiles)  
  • 1

清除网页访问留下的缓存,由于内核缓存是全局的因此这个方法不仅仅针对webview而是针对整个应用程序.

public void clearFormData ()  
  • 1

这个api仅仅清除自动完成填充的表单数据,并不会清除WebView存储到本地的数据。

public void clearHistory ()  
  • 1

清除当前webview访问的历史记录,只会webview访问历史记录里的所有记录除了当前访问记录.

public void clearMatches ()  
  • 1

清除网页查找的高亮匹配字符

public void clearView ()  
  • 1

在Android 4.3及其以上系统这个api被丢弃了, 并且这个api大多数情况下会有bug,经常不能清除掉之前的渲染数据。官方建议通过loadUrl(“about:blank”)来实现这个功能,阴雨需要重新加载一个页面自然时间会收到影响。
6)WebView的状态

这里写代码片
  • 1

public void onResume ()
激活WebView为活跃状态,能正常执行网页的响应

public void onPause ()  
  • 1

当页面被失去焦点被切换到后台不可见状态,需要执行onPause动过, onPause动作通知内核暂停所有的动作,比如DOM的解析、plugin的执行、JavaScript执行。并且可以减少不必要的CPU和网络开销,可以达到省电、省流量、省资源的效果。

public void pauseTimers ()  
  • 1

当应用程序被切换到后台我们使用了webview, 这个方法不仅仅针对当前的webview而是全局的全应用程序的webview,它会暂停所有webview的layout,parsing,javascripttimer。降低CPU功耗。

public void resumeTimers ()  
  • 1

恢复pauseTimers时的动作。

public void destroy ()
Tips(重要)
这个方法必须在webview从view tree中删除之后才能被执行, 这个方法会通知native释放webview占用的所有资源。

7) WebView 事件回调监听

这里写代码片
  • 1

public void setWebChromeClient (WebChromeClient client)
主要通知客户端app加载当前网页的 title,Favicon,progress,javascript dialog等事件,通知客户端处理这些相应的事件。

public void setWebViewClient (WebViewClient client) 
  • 1

主要通知客户端app加载当前网页时的各种时机状态,onPageStart,onPageFinish,onReceiveError等事件。
8) Android 5.0 Lollipop 新API

public static void enableSlowWholeDocumentDraw ()
  • 1

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

  1. WebView Demo
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.ijinshan.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);  
        }  

    }  
}  
  • 1
<uses-permission android:name="android.permission.INTERNET" /> 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

苦茶子12138

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值