轉(zhuǎn)載出處:https://blog.csdn.net/u012519664/article/details/81324022
WebView在現(xiàn)在的項(xiàng)目中使用的頻率應(yīng)該還是非常高的财饥。
我個(gè)人總覺得HTML5是一種趨勢(shì)朴爬。找了一些東西漾峡,在此總結(jié)荆忍。
本篇最后有一個(gè)非常不錯(cuò) 的 Html5Activity 加載類,不想看的可以直接跳下載昵仅。WebSettings
WebSettings?webSettings?=?mWebView?.getSettings();
//支持獲取手勢(shì)焦點(diǎn)退渗,輸入用戶名、密碼或其他
webview.requestFocusFromTouch();
setJavaScriptEnabled(true);//支持js
setPluginsEnabled(true);//支持插件
webSettings.setRenderPriority(RenderPriority.HIGH);//提高渲染的優(yōu)先級(jí)設(shè)置自適應(yīng)屏幕犀勒,兩者合用
setUseWideViewPort(true);//將圖片調(diào)整到適合webview的大小
setLoadWithOverviewMode(true);//?縮放至屏幕的大小
setSupportZoom(true);//支持縮放屎飘,默認(rèn)為true。是下面那個(gè)的前提贾费。
setBuiltInZoomControls(true);//設(shè)置可以縮放
setDisplayZoomControls(false);//隱藏原生的縮放控件
//若上面是false钦购,則該WebView不可縮放,這個(gè)不管設(shè)置什么都不能縮放铸本。setTextZoom(2);//設(shè)置文本的縮放倍數(shù)肮雨,默認(rèn)為?100
setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);//支持內(nèi)容重新布局
supportMultipleWindows();//多窗口
setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);//關(guān)閉webview中緩存
setAllowFileAccess(true);//設(shè)置可以訪問文件
setNeedInitialFocus(true);//當(dāng)webview調(diào)用requestFocus時(shí)為webview設(shè)置節(jié)點(diǎn)
setJavaScriptCanOpenWindowsAutomatically(true);//支持通過JS打開新窗口
setLoadsImagesAutomatically(true);//支持自動(dòng)加載圖片
setDefaultTextEncodingName("utf-8");//設(shè)置編碼格式
setStandardFontFamily("");//設(shè)置?WebView?的字體,默認(rèn)字體為?"sans-serif"
setDefaultFontSize(20);//設(shè)置?WebView?字體的大小箱玷,默認(rèn)大小為?16
setMinimumFontSize(12);//設(shè)置?WebView?支持的最小字體大小怨规,默認(rèn)為?8
關(guān)于緩存
緩存模式:
LOAD_CACHE_ONLY: ?不使用網(wǎng)絡(luò)陌宿,只讀取本地緩存數(shù)據(jù)
LOAD_DEFAULT: (默認(rèn))根據(jù)cache-control決定是否從網(wǎng)絡(luò)上取數(shù)據(jù)。LOAD_NO_CACHE: 不使用緩存波丰,只從網(wǎng)絡(luò)獲取數(shù)據(jù).
LOAD_CACHE_ELSE_NETWORK壳坪,只要本地有,無論是否過期掰烟,或者no-cache爽蝴,都使用緩存中的數(shù)據(jù)。
結(jié)合使用(離線加載):
if(NetStatusUtil.isConnected(getApplicationContext()))?{
????webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);//根據(jù)cache-control決定是否從網(wǎng)絡(luò)上取數(shù)據(jù)纫骑。
}else{
????webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);//沒網(wǎng)蝎亚,則從本地獲取,即離線加載
}
webSettings.setDomStorageEnabled(true);//?開啟?DOM?storage?API?功能webSettings.setDatabaseEnabled(true);//開啟?database?storage?API?功能webSettings.setAppCacheEnabled(true);//開啟?Application?Caches?功能StringcacheDirPath?=?getFilesDir().getAbsolutePath()?+?APP_CACAHE_DIRNAME;webSettings.setAppCachePath(cacheDirPath);//設(shè)置??Application?Caches?緩存目錄
注意:每個(gè) Application 只調(diào)用一次 WebSettings.setAppCachePath()先馆,WebSettings.setAppCacheMaxSize()
加載方式
加載一個(gè)網(wǎng)頁:webView.loadUrl("http://www.google.com/");
加載apk包中的一個(gè)html頁面:webView.loadUrl("file:///android_asset/test.html");
加載手機(jī)本地的一個(gè)html頁面的方法:webView.loadUrl("content://com.android.htmlfileprovider/sdcard/test.html");
添加 HTTP 請(qǐng)求頭(Header)
loadUrl(String url, MapadditionalHttpHeaders)
WebViewClient
WebViewClient就是幫助WebView處理各種通知发框、請(qǐng)求事件的。
打開網(wǎng)頁時(shí)不調(diào)用系統(tǒng)瀏覽器煤墙, 而是在本W(wǎng)ebView中顯示:mWebView.setWebViewClient(newWebViewClient(){
@Override
publicbooleanshouldOverrideUrlLoading(WebView?view,Stringurl)?{
????view.loadUrl(url);
????returntrue;
}
});
WebViewClient方法
WebViewClient?mWebViewClient?=newWebViewClient(){
????shouldOverrideUrlLoading(WebView?view,Stringurl)??最常用的梅惯,比如上面的。
//在網(wǎng)頁上的所有加載都經(jīng)過這個(gè)方法,這個(gè)函數(shù)我們可以做很多操作仿野。
//比如獲取url铣减,查看url.contains(“add”),進(jìn)行添加操作shouldOverrideKeyEvent(WebView?view,?KeyEvent?event)
//重寫此方法才能夠處理在瀏覽器中的按鍵事件脚作。onPageStarted(WebView?view,Stringurl,?Bitmap?favicon)
//這個(gè)事件就是開始載入頁面調(diào)用的葫哗,我們可以設(shè)定一個(gè)loading的頁面,告訴用戶程序在等待網(wǎng)絡(luò)響應(yīng)鳖枕。
onPageFinished(WebView?view,Stringurl)
//在頁面加載結(jié)束時(shí)調(diào)用魄梯。同樣道理,我們可以關(guān)閉loading?條宾符,切換程序動(dòng)作酿秸。
onLoadResource(WebView?view,Stringurl)
//?在加載頁面資源時(shí)會(huì)調(diào)用,每一個(gè)資源(比如圖片)的加載都會(huì)調(diào)用一次魏烫。
shouldInterceptRequest(WebView?view,Stringurl)
//?攔截替換網(wǎng)絡(luò)請(qǐng)求數(shù)據(jù),??API?11開始引入辣苏,API?21棄用
shouldInterceptRequest?(WebView?view,?WebResourceRequest?request)
//?攔截替換網(wǎng)絡(luò)請(qǐng)求數(shù)據(jù),??從API?21開始引入
onReceivedError(WebView?view,interrorCode,Stringdescription,StringfailingUrl)
//?(報(bào)告錯(cuò)誤信息)
doUpdateVisitedHistory(WebView?view,Stringurl,booleanisReload)
//(更新歷史記錄)
onFormResubmission(WebView?view,?Message?dontResend,?Message?resend)
//(應(yīng)用程序重新請(qǐng)求網(wǎng)頁數(shù)據(jù))
onReceivedHttpAuthRequest(WebView?view,?HttpAuthHandler?handler,Stringhost,Stringrealm)
//(獲取返回信息授權(quán)請(qǐng)求)
onReceivedSslError(WebView?view,?SslErrorHandler?handler,?SslErrorerror)
//重寫此方法可以讓webview處理https請(qǐng)求。
onScaleChanged(WebView?view,floatoldScale,floatnewScale)
//?(WebView發(fā)生改變時(shí)調(diào)用)
onUnhandledKeyEvent(WebView?view,?KeyEvent?event)
//(Key事件未被加載時(shí)調(diào)用)
}
將上面定義的WebViewClient設(shè)置給WebView:
webView.setWebViewClient(mWebViewClient);
WebChromeClient
WebChromeClient是輔助WebView處理Javascript的對(duì)話框哄褒,網(wǎng)站圖標(biāo)稀蟋,網(wǎng)站title,加載進(jìn)度等 :
方法中的代碼都是由Android端自己處理呐赡。
WebChromeClient?mWebChromeClient?=newWebChromeClient()?{
//獲得網(wǎng)頁的加載進(jìn)度退客,顯示在右上角的TextView控件中
@Override
publicvoidonProgressChanged(WebView?view,?int?newProgress)?{
if(newProgress?<100)?{
Stringprogress?=?newProgress?+"%";
}else{
}
}
//獲取Web頁中的title用來設(shè)置自己界面中的title
//當(dāng)加載出錯(cuò)的時(shí)候,比如無網(wǎng)絡(luò),這時(shí)onReceiveTitle中獲取的標(biāo)題為?找不到該網(wǎng)頁,
//因此建議當(dāng)觸發(fā)onReceiveError時(shí)萌狂,不要使用獲取到的title
@Override
publicvoidonReceivedTitle(WebView?view,Stringtitle)?{
????MainActivity.this.setTitle(title);
}
@Override
publicvoidonReceivedIcon(WebView?view,?Bitmap?icon)?{
????//
}
@Override
publicbooleanonCreateWindow(WebView?view,booleanisDialog,booleanisUserGesture,?Message?resultMsg)?{
????//
????returntrue;
}
@Override
publicvoidonCloseWindow(WebViewwindow)?{
}
//處理alert彈出框档玻,html?彈框的一種方式
@Override
publicbooleanonJsAlert(WebView?view,Stringurl,Stringmessage,?JsResult?result) {
????//
????returntrue;
}
//處理confirm彈出框
@Override
public booleanonJsPrompt(WebView?view,Stringurl,Stringmessage,StringdefaultValue,?JsPromptResult result)?{
????//
????returntrue;
}
//處理prompt彈出框
@Override
public booleanonJsConfirm(WebView?view,Stringurl,Stringmessage,?JsResult?result)?{
//
returntrue;
}
};
同樣,將上面定義的WebChromeClient設(shè)置給WebView:webView.setWebChromeClient(mWebChromeClient);
WebView 的一些方法
前進(jìn)茫藏、后退
goBack()//后退
goForward()//前進(jìn)
goBackOrForward(intsteps)//以當(dāng)前的index為起始點(diǎn)前進(jìn)或者后退到歷史記錄中指定的steps误趴,
如果steps為負(fù)數(shù)則為后退,正數(shù)則為前進(jìn)
canGoForward()//是否可以前進(jìn)
canGoBack()//是否可以后退
清除緩存數(shù)據(jù):
clearCache(true);//清除網(wǎng)頁訪問留下的緩存务傲,由于內(nèi)核緩存是全局的因此這個(gè)方法不僅僅針對(duì)webview而是針對(duì)整個(gè)應(yīng)用程序.
clearHistory()//清除當(dāng)前webview訪問的歷史記錄凉当,只會(huì)webview訪問歷史記錄里的所有記錄除了當(dāng)前訪問記錄.
clearFormData()//這個(gè)api僅僅清除自動(dòng)完成填充的表單數(shù)據(jù),并不會(huì)清除WebView存儲(chǔ)到本地的數(shù)據(jù)售葡。
WebView的狀態(tài):
onResume()//激活WebView為活躍狀態(tài)看杭,能正常執(zhí)行網(wǎng)頁的響應(yīng)
onPause()//當(dāng)頁面被失去焦點(diǎn)被切換到后臺(tái)不可見狀態(tài),需要執(zhí)行onPause動(dòng)過天通,?onPause動(dòng)作通知內(nèi)核暫停所有的動(dòng)作泊窘,比如DOM的解析、plugin的執(zhí)行像寒、JavaScript執(zhí)行。
pauseTimers()//當(dāng)應(yīng)用程序被切換到后臺(tái)我們使用了webview瓜贾,?這個(gè)方法不僅僅針對(duì)當(dāng)前的webview而是全局的全應(yīng)用程序的webview诺祸,它會(huì)暫停所有webview的layout,parsing祭芦,javascripttimer筷笨。降低CPU功耗。
resumeTimers()//恢復(fù)pauseTimers時(shí)的動(dòng)作龟劲。
destroy()//銷毀胃夏,關(guān)閉了Activity時(shí),音樂或視頻昌跌,還在播放仰禀。就必須銷毀。
但是注意:
webview調(diào)用destory時(shí),webview仍綁定在Activity上.這是由于自定義webview構(gòu)建時(shí)傳入了該Activity的context對(duì)象,因此需要先從父容器中移除webview,然后再銷毀webview:
rootLayout.removeView(webView);
webView.destroy();
判斷WebView是否已經(jīng)滾動(dòng)到頁面底端 或者 頂端:
getScrollY() //方法返回的是當(dāng)前可見區(qū)域的頂端距整個(gè)頁面頂端的距離,也就是當(dāng)前內(nèi)容滾動(dòng)的距離.
getHeight()或者getBottom() //方法都返回當(dāng)前WebView這個(gè)容器的高度
getContentHeight()返回的是整個(gè)html的高度,但并不等同于當(dāng)前整個(gè)頁面的高度,因?yàn)閃ebView有縮放功能,所以當(dāng)前整個(gè)頁面的高度實(shí)際上應(yīng)該是原始html的高度再乘上縮放比例.因此,更正后的結(jié)果,準(zhǔn)確的判斷方法應(yīng)該是:
if(webView.getContentHeight()?*?webView.getScale()?==?(webView.getHeight()?+?webView.getScrollY()))?{
//已經(jīng)處于底端
}
if(webView.getScrollY()?==0){
//處于頂端
?}
返回鍵
返回上一次瀏覽的頁面
public booleanonKeyDown(intkeyCode,?KeyEventevent){
if((keyCode?==?KeyEvent.KEYCODE_BACK)?&&?mWebView.canGoBack())?{
????mWebView.goBack();
????returntrue;
????}
????returnsuper.onKeyDown(keyCode,event);
}
調(diào)用JS代碼
WebSettings?webSettings?=?mWebView?.getSettings();
webSettings.setJavaScriptEnabled(true);
mWebView.addJavascriptInterface(newInsertObj(),"jsObj");
上面這是前提2戏摺4鸲瘛!
然后實(shí)現(xiàn)上面的類萍诱,這個(gè)類提供了四個(gè)方法悬嗓,注釋的非常清楚。
classInsertObjextendsObject{
//給html提供的方法裕坊,js中可以通過:var?str?=?window.jsObj.HtmlcallJava();?獲取到
@JavascriptInterface
publicStringHtmlcallJava(){
return"Html?call?Java";
????}
//給html提供的有參函數(shù)?:?window.jsObj.HtmlcallJava2("IT-homer?blog");
@JavascriptInterface
publicStringHtmlcallJava2(finalString?param){
return"Html?call?Java?:?"+?param;
????}
//Html給我們提供的函數(shù)
@JavascriptInterface
publicvoidJavacallHtml(){
runOnUiThread(newRunnable()?{
@Override
publicvoidrun(){
//這里是調(diào)用方法
mWebView.loadUrl("javascript:?showFromHtml()");
Toast.makeText(Html5Activity.this,"clickBtn",?Toast.LENGTH_SHORT).show();
????????????}
????????});
????}
//Html給我們提供的有參函數(shù)
@JavascriptInterface
publicvoidJavacallHtml2(finalString?param){
runOnUiThread(newRunnable()?{
@Override
publicvoidrun(){
mWebView.loadUrl("javascript:?showFromHtml2('IT-homer?blog')");
Toast.makeText(Html5Activity.this,"clickBtn2",?Toast.LENGTH_SHORT).show();
????????????}
????????});
????}
}
在 WebView 中長按保存圖片
1. 給 WebView添加監(jiān)聽
mWebview.setOnLongClickListener(new?View.OnLongClickListener()?{
@Override
????public?boolean?onLongClick(View?v)?{
????}
});
2. 獲取點(diǎn)擊的圖片地址
先獲取類型包竹,根據(jù)相應(yīng)的類型來處理對(duì)應(yīng)的數(shù)據(jù)。
首先判斷點(diǎn)擊的類型
WebView.HitTestResultresult?=?((WebView)?v).getHitTestResult();
inttype=?result.getType();
type有這幾種類型:
WebView.HitTestResult.UNKNOWN_TYPE ? ?未知類型
WebView.HitTestResult.PHONE_TYPE ? ?電話類型
WebView.HitTestResult.EMAIL_TYPE ? ?電子郵件類型
WebView.HitTestResult.GEO_TYPE ? ?地圖類型
WebView.HitTestResult.SRC_ANCHOR_TYPE ? ?超鏈接類型
WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE ? ?帶有鏈接的圖片類型
WebView.HitTestResult.IMAGE_TYPE ? ?單純的圖片類型
WebView.HitTestResult.EDIT_TEXT_TYPE ? ?選中的文字類型
獲取具體信息,圖片這里就是圖片地址
Stringimgurl?=?result.getExtra();
3. 操作圖片
你可以彈出保存圖片周瞎,或者點(diǎn)擊之后跳轉(zhuǎn)到顯示圖片的頁面悟狱。
最后整理一下代碼:
mWebView.setOnLongClickListener(newView.OnLongClickListener()?{
@Override
publicbooleanonLongClick(View?v)?{
????????WebView.HitTestResult?result?=?((WebView)v).getHitTestResult();
if(null==?result)
returnfalse;
inttype?=?result.getType();
if(type?==?WebView.HitTestResult.UNKNOWN_TYPE)
returnfalse;
//?這里可以攔截很多類型,我們只處理圖片類型就可以了
switch(type)?{
caseWebView.HitTestResult.PHONE_TYPE://?處理撥號(hào)
break;
caseWebView.HitTestResult.EMAIL_TYPE://?處理Email
break;
caseWebView.HitTestResult.GEO_TYPE://?地圖類型
break;
caseWebView.HitTestResult.SRC_ANCHOR_TYPE://?超鏈接
break;
caseWebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE:
break;
caseWebView.HitTestResult.IMAGE_TYPE://?處理長按圖片的菜單項(xiàng)
//?獲取圖片的路徑
????????????????String?saveImgUrl?=?result.getExtra();
//?跳轉(zhuǎn)到圖片詳情頁堰氓,顯示圖片
Intent?i?=newIntent(MainActivity.this,?ImageActivity.class);
????????????????i.putExtra("imgUrl",?saveImgUrl);
????????????????startActivity(i);
break;
default:
break;
????????}
????}
});
Android5.0 WebView中Http和Https混合問題
在Android 5.0上 Webview 默認(rèn)不允許加載 Http 與 Https 混合內(nèi)容:
解決辦法:
if(Build.VERSION.SDK_INT?>=?Build.VERSION_CODES.LOLLIPOP)?{
webView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
}
參數(shù)類型說明:
MIXED_CONTENT_ALWAYS_ALLOW:允許從任何來源加載內(nèi)容挤渐,即使起源是不安全的;
MIXED_CONTENT_NEVER_ALLOW:不允許Https加載Http的內(nèi)容双絮,即不允許從安全的起源去加載一個(gè)不安全的資源浴麻;
MIXED_CONTENT_COMPATIBILITY_MODE:當(dāng)涉及到混合式內(nèi)容時(shí),WebView 會(huì)嘗試去兼容最新Web瀏覽器的風(fēng)格囤攀。
在5.0以下 Android 默認(rèn)是 全允許软免,
但是到了5.0以上,就是不允許焚挠,實(shí)際情況下很我們很難確定所有的網(wǎng)頁都是https的膏萧,所以就需要這一步的操作。
Cookie 相關(guān)
之前同步 cookie 需要用到 CookieSyncManager 類蝌衔,現(xiàn)在這個(gè)類已經(jīng)被拋棄了榛泛。如今 WebView 已經(jīng)可以在需要的時(shí)候自動(dòng)同步 cookie 了,所以不再需要?jiǎng)?chuàng)建 CookieSyncManager 類的對(duì)象來進(jìn)行強(qiáng)制性的同步 cookie 了∝澹現(xiàn)在只需要獲得 CookieManager 的對(duì)象將 cookie 設(shè)置進(jìn)去就可以了曹锨。
前提:
從服務(wù)器的返回頭中取出 cookie 根據(jù)Http請(qǐng)求的客戶端不同,獲取 cookie 的方式也不同剃允,請(qǐng)自行獲取沛简。
1、客戶端通過以下代碼設(shè)置cookie斥废,如果兩次設(shè)置相同椒楣,會(huì)覆蓋上一次的。
/**
?*?將cookie設(shè)置到?WebView
*@paramurl?要加載的?url
*@paramcookie?要同步的?cookie
?*/
publicstaticvoidsyncCookie(Stringurl,Stringcookie)?{
if(Build.VERSION.SDK_INT?<?Build.VERSION_CODES.LOLLIPOP)?{
????????CookieSyncManager.createInstance(context);
????}
????CookieManager?cookieManager?=?CookieManager.getInstance();
cookieManager.setCookie(url,?cookie);//如果沒有特殊需求牡肉,這里只需要將session?id以"key=value"形式作為cookie即可
}
注意:
同步 cookie 要在 WebView 加載 url 之前捧灰,否則 WebView 無法獲得相應(yīng)的 cookie,也就無法通過驗(yàn)證荚板。
cookie應(yīng)該被及時(shí)更新凤壁,否則很可能導(dǎo)致WebView拿的是舊的session id和服務(wù)器進(jìn)行通信。
2跪另、CookieManager會(huì)將這個(gè)Cookie存入該應(yīng)用程序data/data/package_name/app_WebView/Cookies.db
3拧抖、打開網(wǎng)頁,WebView從數(shù)據(jù)庫中讀取該cookie值免绿,放到http請(qǐng)求的頭部唧席,傳遞到服務(wù)器
/**
?*?獲取指定?url?的cookie
?*/
publicstaticStringsyncCookie(Stringurl)?{
????CookieManager?cookieManager?=?CookieManager.getInstance();
returncookieManager.getCookie(url);
}
4、清除Cookie:
//?這個(gè)兩個(gè)在?API?level?21?被拋棄
CookieManager.getInstance().removeSessionCookie();
CookieManager.getInstance().removeAllCookie();
//?推薦使用這兩個(gè),?level?21?新加的
CookieManager.getInstance().removeSessionCookies();//?移除所有過期?cookie
CookieManager.getInstance().removeAllCookies();//?移除所有的?cookie
privatevoidremoveCookie(Context?context)?{
CookieManager.getInstance().removeAllCookies(newValueCallback()?{
@Override
publicvoidonReceiveValue(Booleanvalue)?{
//?清除結(jié)果
????????}
????});
}
避免WebView內(nèi)存泄露的一些方式
1.可以將 Webview 的 Activity 新起一個(gè)進(jìn)程淌哟,結(jié)束的時(shí)候直接System.exit(0);退出當(dāng)前進(jìn)程迹卢;
啟動(dòng)新進(jìn)程,主要代碼: ?AndroidManifest.xml 配置文件代碼如下
android:name=".ui.activity.Html5Activity"
android:process=":lyl.boon.process.web">
在新進(jìn)程中啟動(dòng) Activity 徒仓,里面?zhèn)髁?一個(gè) Url:
Intent?intent?=newIntent("com.lyl.boon.ui.activity.htmlactivity");
Bundle?bundle?=newBundle();
bundle.putString("url",?gankDataEntity.getUrl());
intent.putExtra("bundle",bundle);
????startActivity(intent);
然后在 Html5Activity 的onDestory() 最后加上 System.exit(0); 殺死當(dāng)前進(jìn)程腐碱。
2.不能在xml中定義 Webview ,而是在需要的時(shí)候創(chuàng)建掉弛,并且Context使用 getApplicationgContext()症见,如下代碼:
LinearLayout.LayoutParamsparams=newLinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,?ViewGroup.LayoutParams.MATCH_PARENT);
mWebView?=newWebView(getApplicationContext());
mWebView.setLayoutParams(params);
????????mLayout.addView(mWebView);
3.在 Activity 銷毀的時(shí)候,可以先讓 WebView 加載null內(nèi)容殃饿,然后移除 WebView谋作,再銷毀 WebView,最后置空乎芳。
代碼如下:
@Override
protectedvoidonDestroy(){
if(mWebView?!=null)?{
mWebView.loadDataWithBaseURL(null,"","text/html","utf-8",null);
????????????mWebView.clearHistory();
????????????((ViewGroup)?mWebView.getParent()).removeView(mWebView);
????????????mWebView.destroy();
mWebView?=null;
????????}
super.onDestroy();
????}
有一個(gè)非常不錯(cuò)的 Html5Activity 加載類帖出來:
packagecom.lyl.web;
importandroid.graphics.Bitmap;
importandroid.os.Bundle;
importandroid.os.Message;
importandroid.support.v7.app.AppCompatActivity;
importandroid.util.Log;
importandroid.view.KeyEvent;
importandroid.webkit.GeolocationPermissions;
importandroid.webkit.WebChromeClient;
importandroid.webkit.WebSettings;
importandroid.webkit.WebView;
importandroid.webkit.WebViewClient;
importcom.lyl.test.R;
publicclassHtml5ActivityextendsAppCompatActivity{
privateString?mUrl;
privateLinearLayout?mLayout;
privateWebView?mWebView;
@Override
protectedvoidonCreate(Bundle?savedInstanceState){
super.onCreate(savedInstanceState);
????????setContentView(R.layout.activity_web);
Bundle?bundle?=?getIntent().getBundleExtra("bundle");
mUrl?=?bundle.getString("url");
Log.d("Url:",?mUrl);
????????mLayout?=?(LinearLayout)?findViewById(R.id.web_layout);
LinearLayout.LayoutParams?params?=newLinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,?ViewGroup.LayoutParams.MATCH_PARENT);
mWebView?=newWebView(getApplicationContext());
????????mWebView.setLayoutParams(params);
????????mLayout.addView(mWebView);
????????WebSettings?mWebSettings?=?mWebView.getSettings();
mWebSettings.setSupportZoom(true);
mWebSettings.setLoadWithOverviewMode(true);
mWebSettings.setUseWideViewPort(true);
mWebSettings.setDefaultTextEncodingName("utf-8");
mWebSettings.setLoadsImagesAutomatically(true);
//調(diào)用JS方法.安卓版本大于17,加上注解?@JavascriptInterface
mWebSettings.setJavaScriptEnabled(true);
????????saveData(mWebSettings);
????????newWin(mWebSettings);
????????mWebView.setWebChromeClient(webChromeClient);
????????mWebView.setWebViewClient(webViewClient);
????????mWebView.loadUrl(mUrl);
????}
@Override
publicvoidonPause(){
super.onPause();
????????webView.onPause();
webView.pauseTimers();//小心這個(gè)W裱痢!奈惑!暫停整個(gè)?WebView?所有布局吭净、解析、JS携取。
????}
@Override
publicvoidonResume(){
super.onResume();
????????webView.onResume();
????????webView.resumeTimers();
????}
/**
?????*?多窗口的問題
?????*/
privatevoidnewWin(WebSettings?mWebSettings){
//html中的_bank標(biāo)簽就是新建窗口打開攒钳,有時(shí)會(huì)打不開,需要加以下
//然后?復(fù)寫?WebChromeClient的onCreateWindow方法
mWebSettings.setSupportMultipleWindows(false);
mWebSettings.setJavaScriptCanOpenWindowsAutomatically(true);
????}
/**
?????*?HTML5數(shù)據(jù)存儲(chǔ)
?????*/
privatevoidsaveData(WebSettings?mWebSettings){
//有時(shí)候網(wǎng)頁需要自己保存一些關(guān)鍵數(shù)據(jù),Android?WebView?需要自己設(shè)置
mWebSettings.setDomStorageEnabled(true);
mWebSettings.setDatabaseEnabled(true);
mWebSettings.setAppCacheEnabled(true);
????????String?appCachePath?=?getApplicationContext().getCacheDir().getAbsolutePath();
????????mWebSettings.setAppCachePath(appCachePath);
????}
WebViewClient?webViewClient?=newWebViewClient(){
/**
?????????*?多頁面在同一個(gè)WebView中打開雷滋,就是不新建activity或者調(diào)用系統(tǒng)瀏覽器打開
?????????*/
@Override
publicbooleanshouldOverrideUrlLoading(WebView?view,?String?url){
????????????view.loadUrl(url);
returntrue;
????????}
????};
WebChromeClient?webChromeClient?=newWebChromeClient()?{
//=========HTML5定位==========================================================
//需要先加入權(quán)限
//<uses-permission?android:name="android.permission.INTERNET"/>
//<uses-permission?android:name="android.permission.ACCESS_FINE_LOCATION"/>
//<uses-permission?android:name="android.permission.ACCESS_COARSE_LOCATION"/>
@Override
publicvoidonReceivedIcon(WebView?view,?Bitmap?icon){
super.onReceivedIcon(view,?icon);
????????}
@Override
publicvoidonGeolocationPermissionsHidePrompt(){
super.onGeolocationPermissionsHidePrompt();
????????}
@Override
publicvoidonGeolocationPermissionsShowPrompt(finalString?origin,finalGeolocationPermissions.Callback?callback){
callback.invoke(origin,true,false);//注意個(gè)函數(shù),第二個(gè)參數(shù)就是是否同意定位權(quán)限文兢,第三個(gè)是是否希望內(nèi)核記住
super.onGeolocationPermissionsShowPrompt(origin,?callback);
????????}
//=========HTML5定位==========================================================
//=========多窗口的問題==========================================================
@Override
publicbooleanonCreateWindow(WebView?view,booleanisDialog,booleanisUserGesture,?Message?resultMsg){
????????????WebView.WebViewTransport?transport?=?(WebView.WebViewTransport)?resultMsg.obj;
????????????transport.setWebView(view);
????????????resultMsg.sendToTarget();
returntrue;
????????}
//=========多窗口的問題==========================================================
????};
@Override
publicbooleanonKeyDown(intkeyCode,?KeyEvent?event){
if(keyCode?==?KeyEvent.KEYCODE_BACK?&&?mWebView.canGoBack())?{
????????????mWebView.goBack();
returntrue;
????????}
returnsuper.onKeyDown(keyCode,?event);
????}
@Override
protectedvoidonDestroy(){
super.onDestroy();
if(mWebView?!=null)?{
????????????mWebView.clearHistory();
????????????((ViewGroup)?mWebView.getParent()).removeView(mWebView);
mWebView.loadUrl("about:blank");
????????????mWebView.stopLoading();
mWebView.setWebChromeClient(null);
mWebView.setWebViewClient(null);
????????????mWebView.destroy();
mWebView?=null;
????????}
????}
}
轉(zhuǎn)載筆記
項(xiàng)目地址:https://github.com/Wing-Li/Html5WebView/tree/master