Android WebView 開發詳解(一),androidwebview
概覽:
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
<Webview android:layout_width="match_parent" android:layout_height="match_parent" > </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<String, String> 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<String> 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 {@Overridepublic boolean shouldOverrideUrlLoading(WebView view, String url) {// TODO Auto-generated method stubreturn super.shouldOverrideUrlLoading(view, url);}@Overridepublic void onPageStarted(WebView view, String url, Bitmap favicon) {// TODO Auto-generated method stubsuper.onPageStarted(view, url, favicon);}@Overridepublic void onPageFinished(WebView view, String url) {// TODO Auto-generated method stubsuper.onPageFinished(view, url);}@Overridepublic void onReceivedError(WebView view, int errorCode,String description, String failingUrl) {// TODO Auto-generated method stubsuper.onReceivedError(view, errorCode, description, failingUrl);}@Overridepublic void doUpdateVisitedHistory(WebView view, String url,boolean isReload) {// TODO Auto-generated method stubsuper.doUpdateVisitedHistory(view, url, isReload);}}private WebChromeClientBase mWebChromeClientBase = new WebChromeClientBase();private class WebChromeClientBase extends WebChromeClient {@Overridepublic void onProgressChanged(WebView view, int newProgress) {mActivity.setProgress(newProgress * 1000);}@Overridepublic void onReceivedTitle(WebView view, String title) {// TODO Auto-generated method stubsuper.onReceivedTitle(view, title);}@Overridepublic void onReceivedTouchIconUrl(WebView view, String url,boolean precomposed) {// TODO Auto-generated method stubsuper.onReceivedTouchIconUrl(view, url, precomposed);}@Overridepublic boolean onCreateWindow(WebView view, boolean isDialog,boolean isUserGesture, Message resultMsg) {// TODO Auto-generated method stubreturn super.onCreateWindow(view, isDialog, isUserGesture, resultMsg);}}}
<uses-permission android:name="android.permission.INTERNET" />
轉載請註明出處 http://blog.csdn.net/typename/article/details/39030091 powered by meichal zhao
有問題歡迎討論
android webview的開發問題
沒人回答、
在Android開發中用webView進行操作遇到對於loadUrl的問題
不是只執行了最後一個,是第一個還沒執行完你馬上就讓他執行另一個,看起來就像是只執行了最後一個.
怎麼會同時load兩個url呢? 應該是設計有問題