Android-WebView使用

開發(fā)中使用WebView加載url瞭亮、html標(biāo)簽必不可少仙蚜,比如廣告委粉、活動(dòng)界面通過(guò)WebView加載具有實(shí)效性。下面介紹WebView使用方法栗涂。

webView.loadUrl(url);

loadUrl(url)這樣可以直接加載網(wǎng)頁(yè),但此時(shí)是通過(guò)手機(jī)瀏覽器打開的網(wǎng)頁(yè)忿墅,如果要使用WebView直接打開則需設(shè)置WebViewClient疚脐。

webView.setWebViewClient(new WebViewClient());

有關(guān)WebViewClient下面再詳細(xì)介紹亿柑。

對(duì)于加載Url注意如下:
  1、如果是在線網(wǎng)址記得添加網(wǎng)絡(luò)訪問(wèn)權(quán)限
  2式矫、在線網(wǎng)址中,如果要使用webview打開故慈,記得設(shè)置WebViewClient
  3框全、打開本地html文件時(shí),是不需要設(shè)置WebViewClient拆撼,對(duì)應(yīng)的asstes目錄的url 為:file:///android_asset/xxxxx*

我們先來(lái)看如何根據(jù)需求設(shè)置webView屬性蚜印,可以調(diào)用WebView.getSettings()獲取設(shè)置WebView的WebSettings對(duì)象,通過(guò)WebSettings做屬性配置柒傻,各配置說(shuō)明如下:

        WebSettings webSettings = webView.getSettings();
        //設(shè)置開啟javascript支持
        webSettings.setJavaScriptEnabled(true);
        //設(shè)置支持縮放
        webSettings.setSupportZoom(true);
        //開啟縮放工具(會(huì)出現(xiàn)放大縮小的按鈕)
        webSettings.setBuiltInZoomControls(true);
        //WebView兩種緩存(網(wǎng)頁(yè)预侯、H5)方式,此處網(wǎng)頁(yè)不緩存
        webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);
        //允許JS打開新窗口(默認(rèn)false)
        webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
        //打開本地緩存供JS調(diào)用
        webSettings.setDomStorageEnabled(true);
        //H5緩存內(nèi)存大忻臃肌(已過(guò)時(shí)魄衅,不必設(shè)置已可自動(dòng)管理)
        //webSettings.setAppCacheMaxSize(1024 * 1024 * 8);
        //H5緩存路徑
        String absolutePath = getApplicationContext().getCacheDir().getAbsolutePath();
        //H5緩存大小
        webSettings.setAppCachePath(absolutePath);
        //是否允許WebView訪問(wèn)內(nèi)部文件(默認(rèn)true)
        webSettings.setAllowFileAccess(true);
        //支持存儲(chǔ)H5緩存
        webSettings.setAppCacheEnabled(true);
        //啟動(dòng)概述模式瀏覽界面哲银,當(dāng)頁(yè)面寬度超過(guò)WebView顯示寬度時(shí),縮小頁(yè)面適應(yīng)WebView(默認(rèn)false) 
        webSettings.setLoadWithOverviewMode(true);
        //支持手勢(shì)縮放(如webView中需要手動(dòng)輸入用戶名盲泛、密碼等郁竟,則webview必須設(shè)置支持獲取手勢(shì)焦點(diǎn))
        webView.requestFocusFromTouch();
        // 清除緩存
        webView.clearCache(true);
        // 清除緩存防止登錄上次的賬號(hào)
        CookieManager.getInstance().removeAllCookie();
Java調(diào)用JavaScript

java調(diào)用JavaScript中的函數(shù)很簡(jiǎn)單讥蟆,只需要執(zhí)行如下代碼即可:

webView.loadUrl("javascript:toast()");

toast()是JS中方法。

JavaScript調(diào)用Java

三個(gè)步驟:
  1.調(diào)用WebSettings的setJavaScriptEnabled方法使支持JavaScript調(diào)用玻靡。
  2.調(diào)用WebView的addJavascriptInterface方法將應(yīng)用中的Java對(duì)象暴露給JavaScript邻寿;
  3.在JavaScript腳本中調(diào)用步驟二暴露出來(lái)的Java對(duì)象的方法。

在webView.addJavascriptInterface(new JsBradge(), "android");實(shí)現(xiàn)醋拧;其中JsBradge()中是申明了JS可調(diào)用的本地方法,“android”是與JS協(xié)商的對(duì)象名稱,JS端可通過(guò)android.toastMessage(" ")調(diào)用Java方法沐序。
注:如下需加上@JavascriptInterface注解,避免引起WebView遠(yuǎn)程代碼執(zhí)行漏洞邑时。

    public class JsBradge {
        @JavascriptInterface
        public void toastMessage(String message) {
            Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
        }
    }
WebViewClient

WebViewClient可以拿到WebView在訪問(wèn)網(wǎng)絡(luò)各個(gè)階段的回調(diào)晶丘,包括加載前后,失敗等(以下注釋來(lái)源"啟艦"博客)

/** 
 * 在開始加載網(wǎng)頁(yè)時(shí)會(huì)回調(diào) 
 */  
public void onPageStarted(WebView view, String url, Bitmap favicon)   
/** 
 * 在結(jié)束加載網(wǎng)頁(yè)時(shí)會(huì)回調(diào) 
 */  
public void onPageFinished(WebView view, String url)  
/** 
 * 攔截 url 跳轉(zhuǎn),在里邊添加點(diǎn)擊鏈接跳轉(zhuǎn)或者操作 
 */  
public boolean shouldOverrideUrlLoading(WebView view, String url)  
/** 
 * 加載錯(cuò)誤的時(shí)候會(huì)回調(diào)郁油,在其中可做錯(cuò)誤處理蚕苇,比如再請(qǐng)求加載一次,或者提示404的錯(cuò)誤頁(yè)面 
 */  
public void onReceivedError(WebView view, int errorCode,String description, String failingUrl)  
/** 
 * 當(dāng)接收到https錯(cuò)誤時(shí),會(huì)回調(diào)此函數(shù),在其中可以做錯(cuò)誤處理 
 */  
public void onReceivedSslError(WebView view, SslErrorHandler handler,SslError error)  
/** 
 * 在每一次請(qǐng)求資源時(shí)罗心,都會(huì)通過(guò)這個(gè)函數(shù)來(lái)回調(diào) 
 */  
public WebResourceResponse shouldInterceptRequest(WebView view,  String url) {  
    return null;  
}  

以上可以根據(jù)需求做相應(yīng)處理里伯,其中shouldOverrideUrlLoading方法會(huì)在加載超鏈接時(shí)回調(diào)過(guò)來(lái),當(dāng)需要WAP與原生互調(diào)等劫持URL時(shí)用到,重寫該方法然后return true即可削祈,當(dāng)不需要劫持在else中重新loadUrl(url)即可。

            // 當(dāng)點(diǎn)擊鏈接時(shí),希望覆蓋而不是打開新窗口
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                // showProgressDlg();
                // 攔截?fù)屬?gòu)商品削饵,跳回APP搶購(gòu)商品詳情
                if (url.contains("proId") && url.contains("qgDetail.html")) {

                    String actid = url.split("\\?")[1].split("&")[0].split("=")[1];

                    ActivityController.startActProductDetailActivity(WebActivity.this, actid, "");

                } else if (url.contains("goodDetail.html") && url.contains("proId")) {

                    String id = url.split("\\?")[1].split("&")[0].split("=")[1];

                    ActivityController.startGoodsDetailActivity(WebActivity.this, id);
                } else {
                    view.loadUrl(url);
                }
                return true;
            }
WebChromeClient

可以在其中加載進(jìn)度條,獲取鏈接的標(biāo)題等方法刹碾。

/**
 * 當(dāng)網(wǎng)頁(yè)調(diào)用alert()來(lái)彈出alert彈出框前回調(diào)迷帜,用以攔截alert()函數(shù)
 */
public boolean onJsAlert(WebView view, String url, String message,JsResult result)
/**
 * 當(dāng)網(wǎng)頁(yè)調(diào)用confirm()來(lái)彈出confirm彈出框前回調(diào)物舒,用以攔截confirm()函數(shù)
 */
public boolean onJsConfirm(WebView view, String url, String message,JsResult result)
/**
 * 當(dāng)網(wǎng)頁(yè)調(diào)用prompt()來(lái)彈出prompt彈出框前回調(diào),用以攔截prompt()函數(shù)
 */
 public boolean onJsPrompt(WebView view, String url, String message,String defaultValue, JsPromptResult result) 
 /**
 * 打印 console 信息
 */
 public boolean onConsoleMessage(ConsoleMessage consoleMessage)
 /**
 * 通知程序當(dāng)前頁(yè)面加載進(jìn)度
 */
 public void onProgressChanged(WebView view, int newProgress)

下面附上我項(xiàng)目里的一段代碼,加載進(jìn)度條跟獲取Title:

            @Override
            public void onProgressChanged(WebView view, int newProgress) {
                super.onProgressChanged(view, newProgress);
                if (newProgress == 100) {
                    progressBar.setVisibility(View.GONE);
                } else {
                    if (progressBar.getVisibility() == View.GONE)
                        progressBar.setVisibility(View.VISIBLE);
                    progressBar.setProgress(newProgress);
                }
            }

            @Override
            public void onReceivedTitle(WebView view, String title) {
                setActivityTitle(title);
            }
webView加載html

當(dāng)后臺(tái)返回不是url而是一連串的html標(biāo)簽時(shí),可以通過(guò)

webView.loadDataWithBaseURL(null, html , "text/html", "UTF-8", "");

之前可以設(shè)置:

            //水平不顯示滾動(dòng)條
            webView.setHorizontalScrollBarEnabled(false);
            //垂直不顯示滾動(dòng)條
            webView.setVerticalScrollBarEnabled(false); 

            //初始化壓縮比例
            webView.setInitialScale(50);
            // webview自適應(yīng)屏幕尺寸
            webView.getSettings().setSupportZoom(true);
            webView.getSettings().setUseWideViewPort(true);
            webView.getSettings().setLoadWithOverviewMode(true);
            //設(shè)置圖片顯示方式
            webView.getSettings().setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);

            // 設(shè)置背景色
            //webView.setBackgroundColor(0);

            webView.getSettings().setDefaultTextEncodingName("UTF-8");
            //設(shè)置圖片最大尺寸,高度自適應(yīng)堰怨;文字顏色、字體大小饿肺、行高嵌牺、首行縮進(jìn)兩個(gè)字符
            // 包含去除img style 的js代碼
            String head = "<html><head> <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"> <meta name " +
                    "=\"viewport\" content =\"width=device-width,initial-scale=1, maximum-scale=1, minimum-scale=1," +
                    " user-scalable=no\"/><style type=\"text/css\">" +
                    "p {font-size:14px;line-height:20px;color:#303030;text-indent:2em;} " +
                    "img{max-width:100% ;height:auto !important;} a {color:#3E62A6;}\\u007Fpre {font-size:9pt;line-height:12pt;font-family:Courier New,Arial;border:1px solid #ddd;border-left:5px solid #6CE26C;background:#f6f6f6;padding:5px;}</style></head>"
                    + "<script type=\"text/javascript\"charset=\"utf-8\">window.onload=function(){var imgArr=document.getElementsByTagName(\"img\");for(var i in imgArr){imgArr[i].removeAttribute(\"style\")}}</script>";

            html = head + "<body>" + html + "<script type=\"text/javascript\"charset=\"utf-8\">var imgArr=document.getElementsByTagName(\"img\");for(var i in imgArr){imgArr[i].removeAttribute(\"style\");</script>"
                    + "</body></html>";
回退事件處理

當(dāng)回退時(shí),若不監(jiān)聽回退鍵點(diǎn)擊返回時(shí)不會(huì)回退到上一web界面爸舒,而是直接結(jié)束當(dāng)前Activity蟋字,通過(guò)canGoBack判斷是否可回退,goBack進(jìn)行回退扭勉。代碼如下:

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK && webView.canGoBack()) {
            if (webView.copyBackForwardList().getItemAtIndex(webView.copyBackForwardList().getSize() - 1).getUrl().contains("activity/201412/act_common.html")) {
                //解決活動(dòng)重定向無(wú)法回退到原生界面
                return super.onKeyDown(keyCode, event);
            } else {
                webView.goBack();
                return true;
            }
        }
        return super.onKeyDown(keyCode, event);
    }

以上你看到copyBackForwardList方法鹊奖,這個(gè)是為了解決重定向可以正確退出當(dāng)前Activity而設(shè)置。
先說(shuō)下問(wèn)題涂炎,當(dāng)你loadUrl(url1)時(shí)忠聚,web端將url1更換成了url2,所以顯示出來(lái)的是url2界面唱捣。webview中copyBackForwardList是專門用來(lái)管理url棧的两蟀,但此時(shí),不光url2入棧震缭,url1也入棧了赂毯,所以當(dāng)在url2界面時(shí),canGoBack返回的也是true拣宰,當(dāng)按回退鍵時(shí)就會(huì)回到url1(不會(huì)顯示)然后馬上又回到url2界面党涕,這就是按回退無(wú)法finish當(dāng)前Activity而陷入重新加載url2界面的原因和解決辦法。

注意在擁有WebVie的Activity中需要在onDestory方法中銷毀webView以防內(nèi)存泄漏巡社,代碼如下:

    @Override
    protected void onDestroy() {
        //銷毀webview膛堤,避免內(nèi)在泄漏
        if (webView != null) {
            //移除webView確保Detach
            ViewGroup parent = (ViewGroup) webView.getParent();
            if (parent != null) {
                parent.removeView(webView);
            }
            webView.removeAllViews();
            webView.clearHistory();
            webView.destroy();
            webView = null;
        }
        super.onDestroy();
    }

參考:

WebView使用詳解(二)——WebViewClient與常用事件監(jiān)聽
《Android高級(jí)進(jìn)階》——顧浩鑫/著

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市重贺,隨后出現(xiàn)的幾起案子骑祟,更是在濱河造成了極大的恐慌回懦,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,194評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件次企,死亡現(xiàn)場(chǎng)離奇詭異怯晕,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)缸棵,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門舟茶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人堵第,你說(shuō)我怎么就攤上這事吧凉。” “怎么了踏志?”我有些...
    開封第一講書人閱讀 156,780評(píng)論 0 346
  • 文/不壞的土叔 我叫張陵阀捅,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我针余,道長(zhǎng)饲鄙,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,388評(píng)論 1 283
  • 正文 為了忘掉前任圆雁,我火速辦了婚禮忍级,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘伪朽。我一直安慰自己轴咱,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評(píng)論 5 384
  • 文/花漫 我一把揭開白布烈涮。 她就那樣靜靜地躺著朴肺,像睡著了一般。 火紅的嫁衣襯著肌膚如雪跃脊。 梳的紋絲不亂的頭發(fā)上宇挫,一...
    開封第一講書人閱讀 49,764評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音酪术,去河邊找鬼器瘪。 笑死,一個(gè)胖子當(dāng)著我的面吹牛绘雁,可吹牛的內(nèi)容都是我干的橡疼。 我是一名探鬼主播,決...
    沈念sama閱讀 38,907評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼庐舟,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼欣除!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起挪略,我...
    開封第一講書人閱讀 37,679評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤历帚,失蹤者是張志新(化名)和其女友劉穎滔岳,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體挽牢,經(jīng)...
    沈念sama閱讀 44,122評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡谱煤,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了禽拔。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片刘离。...
    茶點(diǎn)故事閱讀 38,605評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖睹栖,靈堂內(nèi)的尸體忽然破棺而出硫惕,到底是詐尸還是另有隱情,我是刑警寧澤野来,帶...
    沈念sama閱讀 34,270評(píng)論 4 329
  • 正文 年R本政府宣布恼除,位于F島的核電站,受9級(jí)特大地震影響梁只,放射性物質(zhì)發(fā)生泄漏缚柳。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評(píng)論 3 312
  • 文/蒙蒙 一搪锣、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧彩掐,春花似錦构舟、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至朴下,卻和暖如春努咐,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背殴胧。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工渗稍, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人团滥。 一個(gè)月前我還...
    沈念sama閱讀 46,297評(píng)論 2 360
  • 正文 我出身青樓竿屹,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親灸姊。 傳聞我的和親對(duì)象是個(gè)殘疾皇子拱燃,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評(píng)論 2 348

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