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數據。
重新加載頁面
Tip(重要)
頁面所有資源會重新加載
-
public void stopLoading ()
2) 前進後退
-
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();
-
}
-
}
-
-
mWebView.findNext(forward);
5)數據清除部分
-
public void clearCache (boolean includeDiskFiles)
清除網頁訪問留下的緩存,由於內核緩存是全局的因此這個方法不僅僅針對webview而是針對整個應用程序.
-
public void clearFormData ()
這個api僅僅清除自動完成填充的表單數據,並不會清除WebView存儲到本地的數據。
-
public void clearHistory ()
清除當前webview訪問的歷史記錄,只會webview訪問歷史記錄裏的所有記錄除了當前訪問記錄.
-
public void clearMatches ()
清除網頁查找的高亮匹配字符
在Android 4.3及其以上系統這個api被丟棄了, 並且這個api大多數情況下會有bug,經常不能清除掉之前的渲染數據。官方建議通過loadUrl("about:blank")來實現這個功能,陰雨需要重新加載一個頁面自然時間會收到影響。
6)WebView的狀態
激活WebView爲活躍狀態,能正常執行網頁的響應
當頁面被失去焦點被切換到後臺不可見狀態,需要執行onPause動過, onPause動作通知內核暫停所有的動作,比如DOM的解析、plugin的執行、JavaScript執行。並且可以減少不必要的CPU和網絡開銷,可以達到省電、省流量、省資源的效果。
-
public void pauseTimers ()
當應用程序被切換到後臺我們使用了webview, 這個方法不僅僅針對當前的webview而是全局的全應用程序的webview,它會暫停所有webview的layout,parsing,javascripttimer。降低CPU功耗。
-
public void resumeTimers ()
恢復pauseTimers時的動作。
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等事件。
8) Android 5.0 Lollipop 新API
public static void enableSlowWholeDocumentDraw ()
Android 5.0 Webview默認提供減少內存佔用支持,並且智能選擇需要繪製的HTML document部門來提供性能。 當然開發者可以在自己應用程序需要時關閉這個選項(enableSlowWholeDocumentDraw)。
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);
-
-
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) {
-
-
return super.shouldOverrideUrlLoading(view, url);
-
}
-
-
@Override
-
public void onPageStarted(WebView view, String url, Bitmap favicon) {
-
-
super.onPageStarted(view, url, favicon);
-
}
-
-
@Override
-
public void onPageFinished(WebView view, String url) {
-
-
super.onPageFinished(view, url);
-
}
-
-
@Override
-
public void onReceivedError(WebView view, int errorCode,
-
String description, String failingUrl) {
-
-
super.onReceivedError(view, errorCode, description, failingUrl);
-
}
-
-
@Override
-
public void doUpdateVisitedHistory(WebView view, String url,
-
boolean isReload) {
-
-
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) {
-
-
super.onReceivedTitle(view, title);
-
}
-
-
@Override
-
public void onReceivedTouchIconUrl(WebView view, String url,
-
boolean precomposed) {
-
-
super.onReceivedTouchIconUrl(view, url, precomposed);
-
}
-
-
@Override
-
public boolean onCreateWindow(WebView view, boolean isDialog,
-
boolean isUserGesture, Message resultMsg) {
-
-
return 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
有問題歡迎討論