Android WebView使用詳解

一蚌父、WebView的設置

//支持獲取手勢焦點漱挚,輸入用戶名竣灌、密碼或其他
webview.requestFocusFromTouch();
WebSettings webSettings = mWebView .getSettings();
webSettings.setJavaScriptEnabled(true);  //支持js档玻,如果不設置本行谱姓,html中的js代碼都會失效
webSettings.setPluginsEnabled(true);  //支持插件

webSettings.setRenderPriority(RenderPriority.HIGH);  //提高渲染的優(yōu)先級

設置自適應屏幕,兩者合用
webSettings.setUseWideViewPort(true);  //將圖片調(diào)整到適合webview的大小
webSettings.setLoadWithOverviewMode(true); // 縮放至屏幕的大小

webSettings.setSupportZoom(true);  //支持縮放浪腐,默認為true纵揍。是下面那個的前提。
webSettings.setBuiltInZoomControls(true); //設置可以縮放
webSettings.setDisplayZoomControls(false); //隱藏原生的縮放控件
//若上面是false议街,則該WebView不可縮放,這個不管設置什么都不能縮放璧榄。
webSettings.setTextZoom(2);//設置文本的縮放倍數(shù)特漩,默認為 100

webSettings.setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN); //支持內(nèi)容重新布局
webSettings.supportMultipleWindows();  //多窗口
webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);  //關閉webview中緩存
webSettings.setAllowFileAccess(true);  //設置可以訪問文件
webSettings.setNeedInitialFocus(true); //當webview調(diào)用requestFocus時為webview設置節(jié)點
webSettings.setJavaScriptCanOpenWindowsAutomatically(true); //支持通過JS打開新窗口,不明白什么意思
webSettings.setLoadsImagesAutomatically(true);  //支持自動加載圖片
webSettings.setDefaultTextEncodingName("utf-8");//設置編碼格式

webSettings.setStandardFontFamily("");//設置 WebView 的字體骨杂,默認字體為 "sans-serif"
webSettings.setDefaultFontSize(20);//設置 WebView 字體的大小涂身,默認大小為 16
webSettings.setMinimumFontSize(12);//設置 WebView 支持的最小字體大小,默認為 8

以上代碼摘自http://www.reibang.com/p/3fcf8ba18d7f

二搓蚪、webView加載頁面

        //webview加載在線網(wǎng)站
        mWebView.loadUrl("http://www.baidu.com");
        //webview加載assets中的html文件
        mWebView.loadUrl("file:///android_asset/test.html");
        //webview加載位于sdcard上的html文檔
        mWebView.loadUrl("content://com.android.htmlfileprovider/sdcard/test.html");
        //webview加載部分html
        //data的內(nèi)容必須是符合html規(guī)范的String字符串
        mWebView.loadDataWithBaseURL(null,"","text/html","utf-8",null);
        mWebView.loadData("","text/html","utf-8");

三蛤售、webView的兩個Client

1.WebViewClient
      //如果不添加這一行代碼,那么我們的html會使用系統(tǒng)默認瀏覽器打開
        //如果超過一個瀏覽器可選擇,那么會讓用戶自己選擇
        mWebView.setWebViewClient(new WebViewClient() 

難道一個WebViewClient存在的意義就是讓html在App內(nèi)打開悴能?當然不是揣钦,WebViewClient有很多方法,幫我們處理網(wǎng)頁在加載過程中的各種問題,先來看幾個常用的??:

 mWebView.setWebViewClient(new WebViewClient() {
            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                //網(wǎng)頁開始加載的時候調(diào)用
                super.onPageStarted(view, url, favicon);
                Log.d(TAG, "onPageStarted: ");
            }

            @Override
            public void onPageFinished(WebView view, String url) {
                //網(wǎng)頁加載結束的時候調(diào)用
                super.onPageFinished(view, url);
                Log.d(TAG, "onPageFinished: ");
            }

            @Override
            public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
                //攔截url
                Uri url1 = request.getUrl();
                Map<String, String> requestHeaders = request.getRequestHeaders();
                boolean redirect = request.isRedirect();
                
                Log.d(TAG, "shouldOverrideUrlLoading: ");
                return super.shouldOverrideUrlLoading(view, request);
            }
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                  //同上漠酿,只是方法過時了而已
                return super.shouldOverrideUrlLoading(view, url);
            }
            @Override
            public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
                Log.d(TAG, "shouldInterceptRequest: request");
                return super.shouldInterceptRequest(view, request);
            }

            @Override
            public void onLoadResource(WebView view, String url) {
                //網(wǎng)頁中的元素請求資源的時候調(diào)用冯凹,每一次請求都會調(diào)用
                super.onLoadResource(view, url);
                Log.d(TAG, "onLoadResource: ");
            }
        });

這樣看什么問題也看不出來,所以我增加了打印日志的代碼炒嘲,下面看日志:由于打印日志太多宇姚,我把日志圖片截成了兩部分,都是比較重要的部分夫凸。

日志輸出1

日志輸出2

從日志輸出可以看到浑劳,webView在加載一個網(wǎng)頁時所請求的流程:
onPageStarted()--->onLoadResource()--->shouldOverrideUrlLoading--->onPageStarted()--->shouldInterceptRequest--->
onLoadResource--->
shouldInterceptRequest--->
onLoadResource--->...重復
--->onPageFinished--->
shouldInterceptRequest--->
onLoadResource--->...重復
由此可見
1.onPageStarted()會調(diào)用兩遍,而且第一遍并沒有真正請求夭拌,應該只是http建立連接的過程(這個是我猜測的)魔熏,第二次執(zhí)行onPageStarted()才是真正開始加載網(wǎng)頁
2.shouldOverrideUrlLoading在第一次onPageStarted()完成后,會調(diào)用這個方法啼止,用于讓用戶實現(xiàn)攔截url道逗,這是用戶唯一一次攔截url的機會。
3.webview的每一次資源請求前献烦,即調(diào)用onLoadResource()方法前滓窍,都會調(diào)用shouldInterceptRequest()方法來咨詢我們是否需要攔截該請求,或者替換請求數(shù)據(jù)巩那。

為什么onPageFinished()調(diào)用后吏夯,后面還有那么多的請求資源的動作?即横?噪生?還是說因為異步的原因?跪求高手解答

WebViewClient還內(nèi)置了別的很多方法供我們使用

 @Override
            public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
                super.onReceivedSslError(view, handler, error);
                //https請求出錯的時候
            }

            @Override
            public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
                super.onReceivedError(view, request, error);
                //加載網(wǎng)頁出錯
            }

            @Override
            public void onScaleChanged(WebView view, float oldScale, float newScale) {
                super.onScaleChanged(view, oldScale, newScale);
                //縮放改變時
            }

            @Override
            public void onUnhandledKeyEvent(WebView view, KeyEvent event) {
                super.onUnhandledKeyEvent(view, event);
                //未處理鍵盤事件
            }

            @Override
            public boolean shouldOverrideKeyEvent(WebView view, KeyEvent event) {
                return super.shouldOverrideKeyEvent(view, event);
                //處理鍵盤事件
            }

在實際開發(fā)的時候东囚,根據(jù)實際需要重寫必要的方法即可跺嗽,沒有必要全部重寫。

2.WebChromeClient

系統(tǒng)已經(jīng)給我們提供了WebViewClient页藻,那為什么還要一個WebChromeClient呢桨嫁?
沒有比較就沒有傷害,我們來看WebChromeClient中的方法

 mWebView.setWebChromeClient(new WebChromeClient() {

            @Override
            public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
                //處理js中的alert()方法,在alert()之前調(diào)用,return true代表我們自己處理該事件份帐,js中的alert()方法會失效
                //message 是彈框中的內(nèi)容
                return super.onJsAlert(view,url,message,result);
            }

            @Override
            public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
                //處理js中的prompt()方法,在prompt()之前調(diào)用,return true代表我們自己處理該事件璃吧,js中的prompt()方法會失效
                //message 是彈框中的內(nèi)容
                return super.onJsPrompt(view,url,message,defaultValue,result);
            }

            @Override
            public boolean onJsConfirm(WebView view, String url, String message, JsResult result) {
                //處理js中的confirm()方法,confirm()之前調(diào)用,return true代表我們自己處理該事件,js中的confirm()方法會失效
                //message 是彈框中的內(nèi)容
                return super.onJsConfirm(view, url, message, result);
            }

            @Override
            public void onReceivedTitle(WebView view, String title) {
                //title就是網(wǎng)頁中title屬性值
            }

            @Override
            public void onProgressChanged(WebView view, int newProgress) {
                super.onProgressChanged(view, newProgress);
                //newProgress為網(wǎng)頁的加載進度废境,并且這個值并不是有規(guī)律的遞增的畜挨,最大值為100
            }

            @Override
            public void onReceivedIcon(WebView view, Bitmap icon) {
                super.onReceivedIcon(view, icon);
                //icon是網(wǎng)頁的icon
            }
        });

由此可見筒繁,WebChromeClient的主要指責是負責webView處理網(wǎng)站title、網(wǎng)站圖標巴元、加載進度以及js的對話框等
需要強調(diào)的是毡咏,在測試中發(fā)現(xiàn),如果不設置WebChromeClient务冕,那么html代碼的中那幾種彈框也無法正常彈出血当,即使你已經(jīng)設置了webSettings.setJavaScriptEnabled(true)也不管用

總結一下

1.要想WebChromeClient中的方法生效,一定記得給webView設置支持js功能禀忆。
2.要想js的彈框可以正常彈出臊旭,在給webview設置支持js功能的前提下,一定要給webView設置WebChromeClient箩退。

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末离熏,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子戴涝,更是在濱河造成了極大的恐慌滋戳,老刑警劉巖,帶你破解...
    沈念sama閱讀 223,002評論 6 519
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件啥刻,死亡現(xiàn)場離奇詭異奸鸯,居然都是意外死亡,警方通過查閱死者的電腦和手機可帽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,357評論 3 400
  • 文/潘曉璐 我一進店門娄涩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人映跟,你說我怎么就攤上這事蓄拣。” “怎么了努隙?”我有些...
    開封第一講書人閱讀 169,787評論 0 365
  • 文/不壞的土叔 我叫張陵球恤,是天一觀的道長。 經(jīng)常有香客問我荸镊,道長咽斧,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,237評論 1 300
  • 正文 為了忘掉前任躬存,我火速辦了婚禮收厨,結果婚禮上,老公的妹妹穿的比我還像新娘优构。我一直安慰自己,他們只是感情好雁竞,可當我...
    茶點故事閱讀 69,237評論 6 398
  • 文/花漫 我一把揭開白布钦椭。 她就那樣靜靜地躺著拧额,像睡著了一般。 火紅的嫁衣襯著肌膚如雪彪腔。 梳的紋絲不亂的頭發(fā)上侥锦,一...
    開封第一講書人閱讀 52,821評論 1 314
  • 那天,我揣著相機與錄音德挣,去河邊找鬼恭垦。 笑死,一個胖子當著我的面吹牛格嗅,可吹牛的內(nèi)容都是我干的番挺。 我是一名探鬼主播,決...
    沈念sama閱讀 41,236評論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼屯掖,長吁一口氣:“原來是場噩夢啊……” “哼玄柏!你這毒婦竟也來了?” 一聲冷哼從身側響起贴铜,我...
    開封第一講書人閱讀 40,196評論 0 277
  • 序言:老撾萬榮一對情侶失蹤粪摘,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后绍坝,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體徘意,經(jīng)...
    沈念sama閱讀 46,716評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,794評論 3 343
  • 正文 我和宋清朗相戀三年轩褐,在試婚紗的時候發(fā)現(xiàn)自己被綠了椎咧。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,928評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡灾挨,死狀恐怖邑退,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情劳澄,我是刑警寧澤地技,帶...
    沈念sama閱讀 36,583評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站秒拔,受9級特大地震影響莫矗,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜砂缩,卻給世界環(huán)境...
    茶點故事閱讀 42,264評論 3 336
  • 文/蒙蒙 一作谚、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧庵芭,春花似錦妹懒、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,755評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽会前。三九已至,卻和暖如春匾竿,著一層夾襖步出監(jiān)牢的瞬間瓦宜,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,869評論 1 274
  • 我被黑心中介騙來泰國打工岭妖, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留临庇,地道東北人。 一個月前我還...
    沈念sama閱讀 49,378評論 3 379
  • 正文 我出身青樓昵慌,卻偏偏與公主長得像假夺,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子废离,可洞房花燭夜當晚...
    茶點故事閱讀 45,937評論 2 361

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