webview詳解和常見的問題

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容