本篇文章作為我對WebView使用過程中的一個總結(jié)询刹。
1.WebView基本使用果港。在app中顯示在線網(wǎng)址。
設(shè)置權(quán)限
<uses-permissionandroid:name="android.permission.INTERNET"/>```
寫布局文件
<WebView
android:id="@+id/webview"
android:layout_width="match_parent"
android:layout_height="match_parent"/>```
在Acitvity中mWebView.loadUrl(url);
//這種寫法應(yīng)用啟動后會開啟手機(jī)內(nèi)置瀏覽器
要想在應(yīng)用中打開網(wǎng)頁,需要我們在調(diào)用loadUrl前加上如下這句允蚣。
mWebView.setWebViewClient(new WebViewClient());
訪問www.baidu.com征峦。干凈簡潔沒新聞迟几,沒廣告。但是記得我們的url需要寫成http://www.baidu.com栏笆。 WebView是不會添加頭的类腮。
上面我們使用WebViewClient這個類,之后根據(jù)問題再介紹蛉加。
2.在網(wǎng)頁沒出來之前顯示一片空白蚜枢,怎樣知道網(wǎng)頁加載的速度。
更改布局针饥,在LinearLayout布局中增加一個button和一個progress
<Button android:id="@+id/webview_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="點擊加載"/>
<ProgressBar
android:id="@+id/webview_progressbar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="5dp"
android:max="100"
android:progress="0" />```
我們在代碼中自定義類
private class CustomChromeClient extends WebChromeClient{
@Override
public void onProgressChanged(WebView view, int newProgress) {
super.onProgressChanged(view, newProgress);
mProgressBar.setProgress(newProgress);
if (newProgress == mProgressBar.getMax()) {
mProgressBar.setVisibility(View.GONE);
} else {
mProgressBar.setVisibility(View.VISIBLE);
}
}
}同時
mWebView.setWebChromeClient(new CustomChromeClient());```
點擊界面的按鈕厂抽,我們可以看到在按鈕下方的進(jìn)度條,會有一個進(jìn)度丁眼。這個進(jìn)度條的樣式是系統(tǒng)默認(rèn)的樣式筷凤。但是我們發(fā)現(xiàn),我們的進(jìn)度條在加載到100的時候苞七,又重頭加載了一次嵌施。我們可以通過在onProgressChanged打log來跟蹤饲化,進(jìn)度的變化情況。因為我們訪問的是http://www.baidu.com. 這個會自動重定向到一個新的url吗伤。
我們是怎么發(fā)現(xiàn)它定向到一個新的地址的呢吃靠?我們定義了一個類
private class CustomWebViewClient extends WebViewClient{
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
return super.shouldOverrideUrlLoading(view,url);
}
}```
并且添加
```mWebView.setWebChromeClient(new CustomChromeClient());```
運行后,在類里面打日志足淆,會發(fā)現(xiàn)我們的百度的地址做了重定向巢块。我再次用chrome瀏覽器訪問百度的地址,沒有發(fā)現(xiàn)進(jìn)度條出現(xiàn)的狀況巧号。在chrome里顯示新聞以及廣告族奢,在我們的app了沒有。我懷疑是網(wǎng)頁內(nèi)js和css的問題丹鸿。所以設(shè)置了
mWebView.getSettings().setJavaScriptEnabled(true);//支持js```
這樣再次運行的時候就不會出現(xiàn)進(jìn)度條結(jié)束后又重新走的情況越走,我們觀察下shouldOverrideUrlLoading里方法的日志。沒有重定向靠欢。而且顯示新聞和廣告跟chrome瀏覽器里顯示的一樣了廊敌。
3.了解一下WebViewClient
點到這個類里可以看到有好多方法。
1.onPageStarted和onPageFinished
根據(jù)字面意思就是在加載頁面的開始和結(jié)束的時候調(diào)用的方法门怪。
如果我們要顯示一個不用時時更新進(jìn)度的進(jìn)度條骡澈,就可以放在這兩個位置完成進(jìn)度條的隱藏和現(xiàn)實。
2.public boolean shouldOverrideUrlLoading(WebView view, String url) 在onpagestarted方法后 會回調(diào)這個這個方法
在加載url時我們會首先調(diào)用這個方法掷空,攔截要訪問的url肋殴。這個方法的默認(rèn)返回值是false,就是默認(rèn)加載url坦弟。如果返回true為不加載护锤。
如下
mWebView.setWebViewClient(new WebViewClient());
如果我們不setWebViewClient 那么網(wǎng)頁就會在系統(tǒng)瀏覽器中打開。
這個方法能做什么呢酿傍?
-
在webview中打開應(yīng)用
//在方法中添加蔽豺,跳轉(zhuǎn)到應(yīng)用市場。 url="market://details?id=com.instagram.android"; //打開應(yīng)用市場 if(url.startsWith("market:")){ Intent intent = new Intent(Intent.ACTION_VIEW); intent.setData(Uri.parse(url)); if (intent.resolveActivity(getPackageManager()) != null) { //可以接收 startActivity(intent); } return true; } ```
地址替換
在方法里判斷 如果為某一網(wǎng)址拧粪,則替換為其他網(wǎng)址修陡。
如果想在webview中打開,不跳轉(zhuǎn)可霎。
if(url.startsWith("market://")){
String tmpUrl=url.substring(9);
url="https://play.google.com/store/apps/"+tmpUrl;
}```
當(dāng)然我們還可以打開其他應(yīng)用魄鸦。應(yīng)用的地址通常可能是癣朗。pinterest://feed/home?link_click_id=292551922683456291
跟處理market的方法一致拾因。
pinterest://feed/home?類似這樣的url是可以自定義的(設(shè)置啟動activity的data方法里的schema port等參數(shù))。相關(guān)幫助可以搜索“在瀏覽器中打開應(yīng)用”。
#####3.public void onLoadResource(WebView view, String url) 在每次在加載資源前會調(diào)用該方法.
資源有.js .css 圖片類型 鏈接等
private final Pattern imageUrlPattern = Pattern.compile("(.)+\(jpg|gif|png|bmp|jpeg){1}", Pattern.CASE_INSENSITIVE);```
Matcher m = imageUrlPattern.matcher(url);
if (m.find()) {
Log.i(WEBVIEWLOG,"保存這張圖片");
}```
上面的代碼用來獲取后綴符合要求的圖片資源绢记。有些圖片資源的url并沒有.jpg這樣的后綴扁达,那我們需要URLConnect重新去訪問這個資源url,并獲取contentType 根據(jù)這個值來確定是否為圖片蠢熄。
#####4 public WebResourceResponse shouldInterceptRequest(WebView view,String url)
跟上面介紹的類似跪解,也是在加載資源的時候會調(diào)用此方法,這個的調(diào)用在onLoadResource方法之前签孔。
此方法默認(rèn)是返回null叉讥,會加載當(dāng)前頁面的資源。這個方法是在非UI線程里執(zhí)行的饥追,所以如果要更新UI需要使用handler图仓。
我們可以用這個方法來做什么?
可以在返回WebResourceResponse結(jié)果的時候替換為我們期待的結(jié)果但绕,例如救崔,我們替換網(wǎng)頁中的圖片∧笏常或者插入我們本地網(wǎng)頁六孵。
//將網(wǎng)頁替換為本地圖片
@Override
public WebResourceResponse shouldInterceptRequest(WebView view,String url) {
WebResourceResponse response = null;
try {
InputStream input = getAssets().open("Jellyfish.jpg");
response = new WebResourceResponse("image/png", "UTF-8", input);
} catch (IOException e) {
e.printStackTrace();
}
return response;
}```
5.WebViewClient的其他方法
- onFormResubmission 是否重發(fā)post請求,默認(rèn)為不重發(fā)
- doUpdateVisitedHistory 更新訪問歷史
- onReceivedLoginRequest 通知主程序執(zhí)行了自動登錄請求
- onReceivedSslError 接收HTTPS頁面的錯誤
- onReceivedError 接收HTTP頁面的錯誤
參考文章http://blog.csdn.net/harvic880925/article/details/51523983