1.如果訪問的界面中有JavaScript,則webview必須支持javascript。
WebSettings webSetting = webview.getSetting();
webSetting.setJavaScriptEnabled(true);
2.如果頁面中鏈接,如果希望點擊鏈接繼續(xù)在當(dāng)前browser中響應(yīng),而不是新開Android的系統(tǒng)browser中響應(yīng)該鏈接,必須覆蓋webview的WebViewClient對象。
mWebView.setWebViewClient(new WebViewClient(){
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
}
3.如果不做任何處理,瀏覽網(wǎng)頁,點擊系統(tǒng)“Back”鍵,整個Browser會調(diào)用finish()而結(jié)束自身,如果希望瀏覽的網(wǎng)頁回退而不是推出瀏覽器,需要在當(dāng)前Activity中處理并消費掉該Back事件。
public boolean onKeyDown(int keyCode, KeyEventevent) {
if((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack()) {
mWebView.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
4.如果webView中需要用戶手動輸入用戶名、密碼或其他,則webview必須設(shè)置支持獲取手勢焦點。
webview.requestFocusFromTouch();
5.原來是因為WebView默認(rèn)沒有開啟文件下載的功能,如果要實現(xiàn)文件下載的功能,需要設(shè)置WebView的DownloadListener,通過實現(xiàn)自己的DownloadListener來實現(xiàn)文件的下載。具體操作如下:
1、設(shè)置WebView的DownloadListener:
webView.setDownloadListener(new MyWebViewDownLoadListener());
2、實現(xiàn)MyWebViewDownLoadListener這個類,具體可以如下這樣:
private class MyWebViewDownLoadListener implements DownloadListener {
@Override
public void onDownloadStart(String url, String userAgent, String
contentDisposition, String mimeType, long contentLength) {
Uri uri = Uri.parse(url);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
}
}
這只是調(diào)用系統(tǒng)中已經(jīng)內(nèi)置的瀏覽器進行下載,還沒有WebView本身進行的文件下載,
不過,這也基本上滿足我們的應(yīng)用場景了。
WebSettings的常用方法介紹
1.setJavaScriptEnabled(true);
//支持js腳步
2.setPluginsEnabled(true);
//支持插件
3.setUseWideViewPort(false);
//將圖片調(diào)整到適合webview的大小
4.setSupportZoom(true);
//支持變焦控制和手勢縮放
5.setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);
//支持內(nèi)容從新布局
6.supportMultipleWindows();
//多窗口
7.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
//關(guān)閉webview中緩存
8.setAllowFileAccess(true);
//設(shè)置可以訪問文件
9.setNeedInitialFocus(true);
//當(dāng)webview調(diào)用requestFocus時為webview設(shè)置節(jié)點
10.setBuiltInZoomControls(true);
//Sets whether the WebView should use its built-in zoom mechanisms.設(shè)置其webview內(nèi)置的縮放機制
11.setJavaScriptCanOpenWindowsAutomatically(true);
//支持通過JS打開新窗口
12.setLoadsImagesAutomatically(true);
//支持自動加載圖片
WebViewClient的方法全解
1.doUpdateVisitedHistory(WebViewview,Stringurl, boolean isReload)
(更新歷史記錄)
2.onFormResubmission(WebViewview,MessagedontResend,Messageresend)
(應(yīng)用程序重新請求網(wǎng)頁數(shù)據(jù))
3.onLoadResource(WebViewview,Stringurl)
在加載頁面資源時會調(diào)用,每一個資源(比如圖片)的加載都會調(diào)用一次。
4.onPageStarted(WebViewview,Stringurl,Bitmapfavicon)
這個事件就是開始載入頁面調(diào)用的,通常我們可以在這設(shè)定一個loading的頁面,告訴用戶程序在等待網(wǎng)絡(luò)響應(yīng)。
5.onPageFinished(WebViewview,Stringurl)
在頁面加載結(jié)束時調(diào)用。同樣道理,我們知道一個頁面載入完成,于是我們可以關(guān)閉loading 條,切換程序動作。
6.onReceivedError(WebViewview, int errorCode, Stringdescription,StringfailingUrl)
(報告錯誤信息)
7.onReceivedHttpAuthRequest(WebViewview,HttpAuthHandlerhandler,Stringhost,Stringrealm)
(獲取返回信息授權(quán)請求)
8.onReceivedSslError(WebViewview,SslErrorHandlerhandler,SslErrorerror)
重寫此方法可以讓webview處理https請求。
9.onScaleChanged(WebViewview, float oldScale, float newScale)
(WebView發(fā)生改變時調(diào)用)
10.onUnhandledKeyEvent(WebViewview,KeyEventevent)
(Key事件未被加載時調(diào)用)
11.shouldOverrideKeyEvent(WebViewview,KeyEventevent)
重寫此方法才能夠處理在瀏覽器中的按鍵事件。
12.shouldOverrideUrlLoading(WebViewview,Stringurl)
在點擊請求的是鏈接是才會調(diào)用,重寫此方法返回true表明點擊網(wǎng)頁里面的鏈接還是在當(dāng)前的webview里跳轉(zhuǎn),不跳到瀏覽器那邊。這個函數(shù)
我們可以做很多操作,比如我們讀取到某些特殊的URL,于是就可以不打開地址,取消這個操作,進行預(yù)先定義的其他操作。
常用步驟
1、添加上網(wǎng)權(quán)限:
2、設(shè)置webview
WebView webView = new WebView(this);
WebSettings ws = webView.getSettings();
ws.setAppCacheEnabled(true);// 設(shè)置啟動緩存
ws.setAppCacheMaxSize(1024 * 10);// 設(shè)置最大緩存
ws.setSupportZoom(true);// 設(shè)置支持縮放
ws.setBuiltInZoomControls(true);
ws.setCacheMode(WebSettings.LOAD_NO_CACHE);// 設(shè)置緩存模式
// 設(shè)置支持Javascript
ws.setJavaScriptEnabled(true);
ws.setJavaScriptCanOpenWindowsAutomatically(true);
// 緩存,離線應(yīng)用
ws.setAppCacheEnabled(true);
ws.setCacheMode(WebSettings.LOAD_DEFAULT);
ws.setAppCacheMaxSize(1024 * 1024 * 8);
3、獲取網(wǎng)頁對話框
webView.setWebChromeClient(new WebChromeClient() {
@Overridepublic boolean onJsAlert(WebView view, String url, String message,final JsResult result) {
//構(gòu)建一個Builder來顯示網(wǎng)頁中的對話框Builder builder = new Builder(context);
builder.setTitle("警告");
builder.setMessage(message);
builder.setPositiveButton(android.R.string.ok,new AlertDialog.OnClickListener() {
public void onClick(DialogInterface dialog,int which) {// 點擊確定按鈕之后,繼續(xù)執(zhí)行網(wǎng)頁中的操作
result.confirm();
}
});
builder.setCancelable(false);
builder.create();
builder.show();return true;
}
@Overridepublic boolean onJsConfirm(WebView view, String url,
String message, final JsResult result) {// TODO Auto-generated method stub
Builder builder = new Builder(context);
builder.setTitle("confirm");
builder.setMessage(message);
builder.setPositiveButton(android.R.string.ok,new AlertDialog.OnClickListener() {
public void onClick(DialogInterface dialog,int which) {
result.confirm();
}
});
builder.setNegativeButton(android.R.string.cancel,new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int which) {
result.cancel();
}
});
builder.setCancelable(false);
builder.create();
builder.show();
return true;
}
@Overridepublic void onProgressChanged(WebView view, int newProgress) {// 加載進度//
super.onProgressChanged(view, newProgress);
}
});
4、如果希望點擊鏈接由自己處理,而不是新開Android的系統(tǒng)browser中響應(yīng)該鏈接。
給WebView添加一個事件監(jiān)聽對象(WebViewClient)
5、webview取得焦點
6、提示加載對話框
pd=ProgressDialog.show(context, "請稍后", "正在加載中...");
當(dāng)網(wǎng)頁加載完成后,調(diào)用pd.dismiss();
webview和js之間數(shù)據(jù)的傳送操作
Webview與js交互
Webview與js的雙向交互才是android的webview強大所在,也是馬甲精神能夠徹底執(zhí)行的基礎(chǔ)保障。
將WebView接受到的數(shù)據(jù)傳遞給js
首先,webview可以定義一個在其內(nèi)嵌頁面中可以觸發(fā)的事件
wv.addJavascriptInterface(new DemoJavaScriptInterface(), "demo");
private final class DemoJavaScriptInterface {
public void clickonAndroid( final String order){
mHandler.post(new Runnable(){
@Override
public void run(){
sonText="{"name":""+order+""}";
wv.loadUrl("javascript:wave("+jsonText+")");
}
});
}
將js接受到的數(shù)據(jù)傳遞給webview
如果你想獲取頁面的一些處理數(shù)據(jù)并交給webview客戶端處理,可在wave函數(shù)里將數(shù)據(jù)alert,然后webview中重寫WebChromeClient的onJsAlert函數(shù),具體代碼如下:
wv.setWebChromeClient(new MyWebChromeClient());
final class MyWebChromeClient extends WebChromeClient{
//message就是wave函數(shù)里alert的字符串,這樣你就可以在android客戶端里對這個數(shù)據(jù)進行處理
@Override
public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {
result.confirm();
return true;
}
}
loadData和loadDataWithBaseURL區(qū)別
loadData (String data, String mimeType, String encoding)
加載一段HTML代碼時,如果出現(xiàn)中文亂碼問題,
就寫成loadData(String data, "text/html;charset=UTF-8",null)
loadDataWithBaseURL (String baseUrl, String data, String mimeType, String encoding, String historyUrl)
loadDataWithBaseURL()比loadData()多兩個參數(shù),可以指定HTML代碼片段中相關(guān)資源的相對根路徑,也可以指定歷史Url。
兩個方法的其余三個參數(shù)相同。
其次,兩個方法加載的HTML代碼片段有些不同,loadData()中的html data中不能包含'#', '%', '\', '?'四中特殊字符,這
WebView加載本地的css文件,js文件和圖片,主要是覆蓋WebViewClient中的shouldInterceptRequest(View view, String url)方法:
cacheWebview.setWebViewClient(new WebViewClient() {
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
WebResourceResponse response = super.shouldInterceptRequest(view, url);
if (url.contains("weixin_qrcode_258.jpg")){
InputStream inputStream = null;
try {
inputStream = getResources().getAssets().open("weixin_qrcode_258.jpg");
response = new WebResourceResponse("image/png",
"utf-8", inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}else if(url.contains(jsName)){
InputStream is = appRm.getInputStream(R.raw.jquery_min_js);
WebResourceResponse response = new WebResourceResponse("text/javascript","utf-8", is);
}else if(url.contains(cssName)){
InputStream is = appRm.getInputStream(R.raw.css;
WebResourceResponse response = new WebResourceResponse("text/css","utf-8", is);
}
return response;
}
});
加載assets文件夾下面的html資源
webView.loadUrl("file:///android_asset/1.html");
調(diào)用js可能出現(xiàn)的錯誤
Alert無法彈出
你應(yīng)該是沒有設(shè)置WebChromeClient,按照以下代碼設(shè)置
myWebView.setWebChromeClient(new WebChromeClient() {});
Uncaught ReferenceError: functionName is not defined
問題出現(xiàn)原因,網(wǎng)頁的js代碼沒有加載完成,就調(diào)用了js方法。解決方法是在網(wǎng)頁加載完成之后調(diào)用js方法
myWebView.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
//在這里執(zhí)行你想調(diào)用的js函數(shù)
}
});
原文: webview詳解和常見的問題
作者: appzy