Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android WebView 開發詳解(一)

Android WebView 開發詳解(一)

編輯:關於Android編程

概覽:

Android WebView在Android平台上是一個特殊的View, 他能用來顯示網頁,這個類可以被用來在你的app中僅僅顯示一張在線的網頁,還可以用來開發浏覽器。WebView內部實現是采用渲染引擎來展示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的內容。

1.WebView的基本使用

(1)創建WebView的實例加入到Activity view tree中

 

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

 

(2)在xml中配置WebView

 

    
    
(3)訪問網頁

 

 

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

2.WebView API使用詳解

1)請求加載網頁部分
public void loadData (String data, String mimeType, String encoding)

 

加載指定的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)
使用baseUrl加載base URL的網頁內容,baseUrl解決相關url使用Javascript相同源問題。

 

 

public void loadUrl (String url)
加載制定url的網頁內容

 

 

public void loadUrl (String url, Map additionalHttpHeaders)

加載制定url並攜帶http header數據。

 

public void reload ()

重新加載頁面

Tip(重要)

頁面所有資源會重新加載

 

public void stopLoading ()

 

 

2) 前進後退

 

public void goBack ()
public void goForward ()
public void goBackOrForward (int steps)
以當前的index為起始點前進或者後退到歷史記錄中指定的steps, 如果steps為負數則為後退,正數則為前進

 

 

public boolean canGoForward ()
public boolean canGoBack ()

 

3)JavaScript操作

 

public void addJavascriptInterface (Object object, String name)

當網頁需要和App進行交互時,可以注入Java對象提供給JavaScritp調用. Java對象提供相應的方法供js使用.

 

Tips(重要)

問題:在Android 4.2以下使用這個api會涉及到JavaScript安全問題, javascript可以通過反射這個java對象的相關類進行攻擊。

解決:可以采用白名單的機制調用這個方法.

在Android4.2極其以上系統需要給提供js調用的方法前加入一個注視:@JavaScriptInterface; 在虛擬機當中 Javascript調用Java方法會檢測這個anotation,如果方法被標識@JavaScriptInterface則Javascript可以成功調用這個Java方法,否則調用不成功。

example:

 

 class JsObject {
    @JavascriptInterface
    public String toString() { return injectedObject; }
 }
 webView.addJavascriptInterface(new JsObject(), injectedObject);

public void evaluateJavascript (String script, ValueCallback resultCallback)
這個方法在Android 4.4系統引入,因此只能在Android4.4系統中才能使用,提供在當前頁面顯示上下文中異步執行javascript代碼

 

Tips(重要)

這個方法必須在UI線程調用,這個函數的回調也會在UI線程執行。

那麼在Android4.4一下如何執行javascrit代碼呢

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

 

webView.loadUrl(javascript:alert(injectedObject.toString()));

其中javascript: 是執行javascript代碼的標識 , 後面是javascript語句。

 

public void removeJavascriptInterface (String name)
刪除addJavascripInterface時對webview注入的java對象. 此方法在不同的Android系統WebView會有問題,會存在失效情況。

 

4)網頁查找功能

 

public int findAll (String find)
這個API在Android 4.1 就已經被去除, 在Android 4.1極其以上系統使用findAllAsync方法

 

這個API還存在bug 具體請見我的之前一篇博文Android WebView findAll bug

 

public void findAllAsync (String find)
異步執行查找網頁內包含的字符並設置高亮,查找結果會回調.

 

 

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);

5)數據清除部分

 

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)來實現這個功能,陰雨需要重新加載一個頁面自然時間會收到影響。

 

6)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 ()
Tips(重要)

 

這個方法必須在webview從view tree中刪除之後才能被執行, 這個方法會通知native釋放webview占用的所有資源。

7) WebView 事件回調監聽

 

public void setWebChromeClient (WebChromeClient client)
主要通知客戶端app加載當前網頁的 title,Favicon,progress,javascript dialog等事件,通知客戶端處理這些相應的事件。

 

 

public void setWebViewClient (WebViewClient client)
主要通知客戶端app加載當前網頁時的各種時機狀態,onPageStart,onPageFinish,onReceiveError等事件。

 

 

3. 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. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved