生活随笔
收集整理的這篇文章主要介紹了
Android WebView 开发详解(一)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
轉載請注明出處 ?http://blog.csdn.net/typename/article/details/39030091?powered by meichal zhao??
概覽:
? ? ? ? ? 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中 ??
[java]?view plaincopy
WebView?webview?=?new?WebView(this);?? setContentView(webview);??
? (2)在xml中配置WebView
[html]?view plaincopy
<Webview?? ????android:layout_width="match_parent"?? ????android:layout_height="match_parent"?>?? </Webview>??
? (3)訪問網頁
[html]?view plaincopy
webview.loadUrl("http://developer.android.com/");??
2.WebView API使用詳解
1)請求加載網頁部分
[java]?view plaincopy
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
[java]?view plaincopy
public?void?loadDataWithBaseURL?(String?baseUrl,?String?data,?String?mimeType,?String?encoding,?String?historyUrl)??
使用baseUrl加載base URL的網頁內容,baseUrl解決相關url使用Javascript相同源問題。
[java]?view plaincopy
public?void?loadUrl?(String?url)??
加載制定url的網頁內容
[java]?view plaincopy
public?void?loadUrl?(String?url,?Map<String,?String>?additionalHttpHeaders)??
加載制定url并攜帶http header數據。
[java]?view plaincopy
public?void?reload?()??
重新加載頁面
Tip(重要)
頁面所有資源會重新加載
[java]?view plaincopy
public?void?stopLoading?()??
2) 前進后退
[java]?view plaincopy
public?void?goBack?()??
[java]?view plaincopy
public?void?goForward?()??
[java]?view plaincopy
public?void?goBackOrForward?(int?steps)??
以當前的index為起始點前進或者后退到歷史記錄中指定的steps, ?如果steps為負數則為后退,正數則為前進
[java]?view plaincopy
public?boolean?canGoForward?()??
[java]?view plaincopy
public?boolean?canGoBack?()??
3)JavaScript操作
[java]?view plaincopy
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:
[java]?view plaincopy
class?JsObject?{?? ???@JavascriptInterface?? ???public?String?toString()?{?return?"injectedObject";?}?? }?? webView.addJavascriptInterface(new?JsObject(),?"injectedObject");??
[java]?view plaincopy
public?void?evaluateJavascript?(String?script,?ValueCallback<String>?resultCallback)??
這個方法在Android 4.4系統引入,因此只能在Android4.4系統中才能使用,提供在當前頁面顯示上下文中異步執行javascript代碼
Tips(重要)
這個方法必須在UI線程調用,這個函數的回調也會在UI線程執行。
那么在Android4.4一下如何執行javascrit代碼呢
可以通過 WebView提供的loadUrl方法:具體格式如下:
[java]?view plaincopy
webView.loadUrl("javascript:alert(injectedObject.toString())");??
其中javascript: 是執行javascript代碼的標識 , 后面是javascript語句。
[java]?view plaincopy
public?void?removeJavascriptInterface?(String?name)??
刪除addJavascripInterface時對webview注入的java對象. 此方法在不同的Android系統WebView會有問題,會存在失效情況。
4)網頁查找功能
[java]?view plaincopy
public?int?findAll?(String?find)??
這個API在Android 4.1 就已經被去除, 在Android 4.1極其以上系統使用findAllAsync方法
這個API還存在bug 具體請見我的之前一篇博文Android WebView findAll bug
[java]?view plaincopy
public?void?findAllAsync?(String?find)??
異步執行查找網頁內包含的字符并設置高亮,查找結果會回調.
[java]?view plaincopy
public?void?findNext?(boolean?forward)??
查找下一個匹配的字符
使用example:
[java]?view plaincopy
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)數據清除部分
[java]?view plaincopy
public?void?clearCache?(boolean?includeDiskFiles)??
清除網頁訪問留下的緩存,由于內核緩存是全局的因此這個方法不僅僅針對webview而是針對整個應用程序.
[java]?view plaincopy
public?void?clearFormData?()??
這個api僅僅清除自動完成填充的表單數據,并不會清除WebView存儲到本地的數據。
[java]?view plaincopy
public?void?clearHistory?()??
清除當前webview訪問的歷史記錄,只會webview訪問歷史記錄里的所有記錄除了當前訪問記錄.
[java]?view plaincopy
public?void?clearMatches?()??
清除網頁查找的高亮匹配字符
[java]?view plaincopy
public?void?clearView?()??
在Android 4.3及其以上系統這個api被丟棄了, 并且這個api大多數情況下會有bug,經常不能清除掉之前的渲染數據。官方建議通過loadUrl("about:blank")來實現這個功能,陰雨需要重新加載一個頁面自然時間會收到影響。
6)WebView的狀態
[java]?view plaincopy
public?void?onResume?()??
激活WebView為活躍狀態,能正常執行網頁的響應
[java]?view plaincopy
public?void?onPause?()??
當頁面被失去焦點被切換到后臺不可見狀態,需要執行onPause動過, onPause動作通知內核暫停所有的動作,比如DOM的解析、plugin的執行、JavaScript執行。并且可以減少不必要的CPU和網絡開銷,可以達到省電、省流量、省資源的效果。
[java]?view plaincopy
public?void?pauseTimers?()??
當應用程序被切換到后臺我們使用了webview, 這個方法不僅僅針對當前的webview而是全局的全應用程序的webview,它會暫停所有webview的layout,parsing,javascripttimer。降低CPU功耗。
[java]?view plaincopy
public?void?resumeTimers?()??
恢復pauseTimers時的動作。
[java]?view plaincopy
public?void?destroy?()??
Tips(重要)
這個方法必須在webview從view tree中刪除之后才能被執行, 這個方法會通知native釋放webview占用的所有資源。
7) WebView 事件回調監聽
[java]?view plaincopy
public?void?setWebChromeClient?(WebChromeClient?client)??
主要通知客戶端app加載當前網頁的 title,Favicon,progress,javascript dialog等事件,通知客戶端處理這些相應的事件。
[java]?view plaincopy
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
[java]?view plaincopy
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);?? ????????}?? ?????????? ????}?? }??
[html]?view plaincopy
<uses-permission?android:name="android.permission.INTERNET"?/>??
轉載請注明出處 ?http://blog.csdn.net/typename/article/details/39030091?powered by meichal zhao
與50位技術專家面對面20年技術見證,附贈技術全景圖
總結
以上是生活随笔為你收集整理的Android WebView 开发详解(一)的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。