Android中的WebView使用

1、基礎(chǔ)用法

1)加載本地assert目錄下文件(error.html)

webcontent.loadUrl(" file:///android_asset/error.html ");

2)加載網(wǎng)絡(luò)url(http://www.csdn.com)

webcontent.loadUrl(" http://www.csdn.com ");

3)加載 String 類型html

String errorHtml = "<html><body><h1>Page not find!</h1></body></html>";

webcontent.loadData(errorHtml,"text/html", "UTF-8");

4)加載SD卡html:

webcontent.loadUrl(" content://com.android.htmlfileprovider/sdcard/kris.html ");

注意:

加載html代碼片段的時候解恰,水平方向適應(yīng)全屏效果不好

解決思路:將“代碼片段”補充為“完成的html代碼”(參考:https://blog.csdn.net/u011692041/article/details/51063540

解決方法:

/**

* 將html片段拼接成完整的html代碼

* 優(yōu)點:為了更好的自適應(yīng)全屏顯示

*

* @param excerptHtml

* @return

*/

private String getCompleteHtml(String excerptHtml) {

? ? StringBuilder sb = new StringBuilder();

? ? String codeStart = "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\"http://www.w3.org/TR/html4/loose.dtd\">" +

? ? ? ? ? ? ? ? "<html>" +

? ? ? ? ? ? ? ? "<head>" + "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover\">" +

? ? ? ? ? ? ? ? "<style>img{width:100% !important;}</style>" +

? ? ? ? ? ? ? ? "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=\"></head>" + "<body style='word-wrap:break-word;font-family:Arial;'>";

? ? ? ? String codeEnd = "</body></html>";

? ? return sb.append(codeStart).append(excerptHtml).append(codeEnd).toString();

}

2霉撵、webView與js通信

1) Android調(diào)用JS代碼

主要有兩種方法:

? ● 通過WebView的loadUrl()

// 調(diào)用javascript的callJS()方法

mWebView.loadUrl("javascript:callJS()");

但是這種不常用,因為它會自動刷新頁面而且沒有返回值帘撰,有點影響交互跑慕。

? ● 通過WebView的evaluateJavascript()

mWebView.evaluateJavascript("javascript:callJS()", new ValueCallback<String>() {

? ? ? ? @Override

? ? ? ? public void onReceiveValue(String value) {

? ? ? ? ? ? //此處為 js 返回的結(jié)果

? ? ? ? }

? ? });

這種就比較全面了。調(diào)用方法并且獲取返回值摧找。

2) JS調(diào)用Android端代碼

主要有兩種方法:

? ● 通過WebView的addJavascriptInterface()進行對象映射

public class AndroidtoJs extends Object {

? ? // 定義JS需要調(diào)用的方法

? ? // 被JS調(diào)用的方法必須加入@JavascriptInterface注解

? ? @JavascriptInterface

? ? public void hello(String msg) {

? ? ? ? System.out.println("JS調(diào)用了Android的hello方法");

? ? }

}

mWebView.addJavascriptInterface(new AndroidtoJs(), "test");

//js中:

function callAndroid(){

? ? // 由于對象映射核行,所以調(diào)用test對象等于調(diào)用Android映射的對象

? ? test.hello("js調(diào)用了android中的hello方法");

}

這種方法雖然很好用,但是要注意的是4.2以后蹬耘,對于被調(diào)用的函數(shù)以@JavascriptInterface進行注解芝雪,否則容易出發(fā)漏洞,因為js方可以通過反射調(diào)用一些本地命令婆赠,很危險绵脯。

? ● 通過WebViewClient 的shouldOverrideUrlLoading ()方法回調(diào)攔截 url

這種方法是通過shouldOverrideUrlLoading回調(diào)去攔截url,然后進行解析休里,如果是之前約定好的協(xié)議蛆挫,就調(diào)用相應(yīng)的方法。

// 復(fù)寫WebViewClient類的shouldOverrideUrlLoading方法

mWebView.setWebViewClient(new WebViewClient() {

? ? ? ? @Override

? ? ? ? public boolean shouldOverrideUrlLoading(WebView view, String url) {

? Uri uri = Uri.parse(url);? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

? ? ? ? ? ? // 如果url的協(xié)議 = 預(yù)先約定的 js 協(xié)議

? ? ? ? ? ? if ( uri.getScheme().equals("js")) {

? // 如果 authority? = 預(yù)先約定協(xié)議里的 webview妙黍,即代表都符合約定的協(xié)議

? ? ? ? ? ? if (uri.getAuthority().equals("webview")) {

? ? ? ? ? ? ? System.out.println("js調(diào)用了Android的方法");

? ? ? ? ? ? ? // 可以在協(xié)議上帶有參數(shù)并傳遞到Android上

? ? ? ? ? ? ? HashMap<String, String> params = new HashMap<>();

? ? ? ? ? ? ? Set<String> collection = uri.getQueryParameterNames();

? ? }

? ? ? ? ? ? return true;

? ? ? ? ? ? }

? ? ? ? ? ? return super.shouldOverrideUrlLoading(view, url);

? ? ? ? ? ? }

? ? ? ? }

? ? );

3悴侵、如何避免WebView內(nèi)存泄露

WebView的內(nèi)存泄露主要是因為在頁面銷毀后,WebView的資源無法馬上釋放所導(dǎo)致的∈眉蓿現(xiàn)在主流的是兩種方法:

1)不在xml布局中添加webview標簽可免,采用在代碼中new出來的方式,并在頁面銷毀的時候去釋放webview資源

//addview

private WeakReference<BaseWebActivity> webActivityReference = new WeakReference<BaseWebActivity>(this);

mWebView = new BridgeWebView(webActivityReference .get());

webview_container.addView(mWebView);

//銷毀

ViewParent parent = mWebView.getParent();

if (parent != null) {

? ? ((ViewGroup) parent).removeView(mWebView);

}

mWebView.stopLoading();

mWebView.getSettings().setJavaScriptEnabled(false);

mWebView.clearHistory();

mWebView.clearView();

mWebView.removeAllViews();

mWebView.destroy()做粤;

mWebView=null浇借;

2)另起一個進程加載webview,頁面銷毀后干掉這個進程怕品。但是這個方法的麻煩之處就在于進程間通信妇垢。

使用方法很簡單,xml文件中寫出進程名即可肉康,銷毀的時候調(diào)用System.exit(0)

<activity android:name=".WebActivity"

? android:process=":remoteweb"/>

System.exit(0)?

4砖顷、webView還有哪些可以優(yōu)化的地方

? ● 提前初始化或者使用全局WebView嫡纠。首次初始化WebView會比第二次初始化慢很多。初始化后逢享,即使WebView已釋放芯肤,但一些多WebView共用的全局服務(wù)/資源對想仍未釋放蹂空,而第二次初始化不需要生成膏燕,因此初始化變快。

? ● DNS采用和客戶端API相同的域名献丑,DNS解析也是耗時比較多的部分,所以用客戶端API相同的域名因為其DNS會被緩存光督,所以打開webView的時候就不會再耗時在DNS上了

? ● 對于JS的優(yōu)化阳距,盡量不要用偏重的框架,比如React结借。其次是高性能要求頁面還是需要后端渲染。最后就是app中的網(wǎng)頁框架要統(tǒng)一卒茬,這樣就可以對js進行緩存和復(fù)用船老。

這里有美團團隊的總結(jié)方案,如下:

? ● WebView初始化慢圃酵,可以在初始化同時先請求數(shù)據(jù)柳畔,讓后端和網(wǎng)絡(luò)不要閑著。

? ● 后端處理慢郭赐,可以讓服務(wù)器分trunk輸出薪韩,在后端計算的同時前端也加載網(wǎng)絡(luò)靜態(tài)資源。

? ● 腳本執(zhí)行慢捌锭,就讓腳本在最后運行俘陷,不阻塞頁面解析。

? ● 同時观谦,合理的預(yù)加載拉盾、預(yù)緩存可以讓加載速度的瓶頸更小。

? ● WebView初始化慢豁状,就隨時初始化好一個WebView待用捉偏。

? ● DNS和鏈接慢,想辦法復(fù)用客戶端使用的域名和鏈接泻红。

? ● 腳本執(zhí)行慢夭禽,可以把框架代碼拆分出來,在請求頁面之前就執(zhí)行好谊路。

5讹躯、webview常見問題

1)https://mp.weixin.qq.com/s/OBGHYCuSYQbGRfrR6whuCg

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(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
  • 正文 為了忘掉前任噩茄,我火速辦了婚禮下面,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘绩聘。我一直安慰自己沥割,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 69,237評論 6 398
  • 文/花漫 我一把揭開白布凿菩。 她就那樣靜靜地躺著机杜,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蓄髓。 梳的紋絲不亂的頭發(fā)上叉庐,一...
    開封第一講書人閱讀 52,821評論 1 314
  • 那天,我揣著相機與錄音会喝,去河邊找鬼陡叠。 笑死,一個胖子當(dāng)著我的面吹牛肢执,可吹牛的內(nèi)容都是我干的枉阵。 我是一名探鬼主播,決...
    沈念sama閱讀 41,236評論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼预茄,長吁一口氣:“原來是場噩夢啊……” “哼兴溜!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起耻陕,我...
    開封第一講書人閱讀 40,196評論 0 277
  • 序言:老撾萬榮一對情侶失蹤拙徽,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后诗宣,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體膘怕,經(jīng)...
    沈念sama閱讀 46,716評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,794評論 3 343
  • 正文 我和宋清朗相戀三年召庞,在試婚紗的時候發(fā)現(xiàn)自己被綠了岛心。 大學(xué)時的朋友給我發(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
  • 正文 我出身青樓咳焚,卻偏偏與公主長得像,于是被迫代替她去往敵國和親庞溜。 傳聞我的和親對象是個殘疾皇子革半,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,937評論 2 361

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

  • 本文轉(zhuǎn)載自 作者:騎著蝸牛闖紅燈原文鏈接 如有侵權(quán),請聯(lián)系我及時刪除流码,本文只做自我學(xué)習(xí)之用又官。 先簡單介紹一下,An...
    全幼兒園最帥_bf2b閱讀 535評論 0 0
  • Android和H5、Js進行交互調(diào)用 Android開發(fā)過程中商虐,我們或多或少都會用到webview觉阅,使用webv...
    Margaret_lhp閱讀 1,847評論 0 0
  • 雖然你們是扮演路人甲乙丙丁崖疤,但是一樣是有生命,有靈魂的典勇〗俸撸”——《喜劇之王》 前言 在開發(fā)原生Android應(yīng)用過程...
    尹天酬閱讀 3,784評論 0 6
  • ips 由于WebView的用法實在太多,如果您只是想查詢某個功能的使用——建議Ctrl+F(Commad+F)在...
    LouisLau_6d51閱讀 1,400評論 0 12
  • WebView·開車指南 2016-08-31BugDev 北京市東城區(qū)首席Bug布道師開山之作割笙,一整月交通事故血...
    53c021c38a1d閱讀 833評論 0 1