Android WebView

轉(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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末晤斩,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子姆坚,更是在濱河造成了極大的恐慌澳泵,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,482評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件兼呵,死亡現(xiàn)場(chǎng)離奇詭異兔辅,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)击喂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門维苔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人懂昂,你說我怎么就攤上這事介时。” “怎么了?”我有些...
    開封第一講書人閱讀 152,762評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵沸柔,是天一觀的道長循衰。 經(jīng)常有香客問我,道長褐澎,這世上最難降的妖魔是什么会钝? 我笑而不...
    開封第一講書人閱讀 55,273評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮工三,結(jié)果婚禮上迁酸,老公的妹妹穿的比我還像新娘。我一直安慰自己徒蟆,他們只是感情好胁出,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,289評(píng)論 5 373
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著段审,像睡著了一般全蝶。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上寺枉,一...
    開封第一講書人閱讀 49,046評(píng)論 1 285
  • 那天抑淫,我揣著相機(jī)與錄音,去河邊找鬼姥闪。 笑死始苇,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的筐喳。 我是一名探鬼主播催式,決...
    沈念sama閱讀 38,351評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼避归!你這毒婦竟也來了荣月?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,988評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤梳毙,失蹤者是張志新(化名)和其女友劉穎哺窄,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體账锹,經(jīng)...
    沈念sama閱讀 43,476評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡萌业,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,948評(píng)論 2 324
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了奸柬。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片生年。...
    茶點(diǎn)故事閱讀 38,064評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖鸟缕,靈堂內(nèi)的尸體忽然破棺而出晶框,到底是詐尸還是另有隱情排抬,我是刑警寧澤,帶...
    沈念sama閱讀 33,712評(píng)論 4 323
  • 正文 年R本政府宣布授段,位于F島的核電站蹲蒲,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏侵贵。R本人自食惡果不足惜届搁,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,261評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望窍育。 院中可真熱鬧卡睦,春花似錦、人聲如沸漱抓。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽乞娄。三九已至瞬逊,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間仪或,已是汗流浹背确镊。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評(píng)論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留范删,地道東北人蕾域。 一個(gè)月前我還...
    沈念sama閱讀 45,511評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像到旦,于是被迫代替她去往敵國和親旨巷。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,802評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容