Android中一個用於網頁顯示的控件,實際上,也可以看做一個功能最小化的瀏覽器,看起來類似於在微信中打開網頁鏈接的頁面。WebView主要用於在app應用中方便地訪問遠程網頁或本地html資源。同時,WebView也在Android中充當Java代碼和JS代碼之間交互的橋樑。
WebView基本用法
設置WebView至少有兩種方法
1、佈局文件中添加WebView控件 & Activity中設置加載頁面
2、調用setContentView()方法,直接通過代碼創建
一般採用第一種方法,在 Activity中設置加載頁面步驟如下
設置加載網址並使用loadUrl()方法加載
對變量private WebView wView;、
1、電腦本地文件:放在app/src/main/assets下的html
wView.loadUrl("file:///android_asset/test.html");
2、手機本地文件
wView.loadUrl("content://com.android.htmlfileprovider/sdcard/test.html");
遠程資源:
需先在清單文件 AndroidManifest文件中爲app申請網絡使用權限:
<uses-permission android:name="android.permission.INTERNET"/>
填入網頁地址進行加載
wView.loadUrl("https://www.cnblogs.com/ifever/")
加載 HTML 頁面的一小段內容
wView.loadData(String data, String mimeType, String encoding)
默認情況下,WebView會調用系統默認瀏覽器加載傳入的網址或者資源。如果需要在當前app頁面內加載,則需要設置WebViewClient 中的shouldOverrideUrlLoading()方法
在當前app頁面內加載
wView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
return false;
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
return false;
}
}
以上兩個方法都會在WebView加載新的url時觸發。
Android 5.0以下系統會回調第一個方法,反之回調第二個方法。因此,爲了兼容不同的系統版本,可以同時重寫這兩個方法。
可以看到,這兩個方法都有一個boolean返回值。假如修改爲true,會帶來重定向問題。
返回鍵始終無法退出應用:重定向問題
設置true的代碼如下
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
//手動加載
return true;
}
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
view.loadUrl(request.getUrl().toString());
//手動加載
return true;
}
雖然不會影響加載,不過會帶來用戶點擊回退鍵始終無法退出應用的問題,下面簡單介紹下原理:
假設訪問網頁過程爲A - > B - > C共三個站點,在C時點回退,C - > B沒問題,接着再點 B -> A,這個時候問題出現了。儘管B來到了A,但是因爲重定向又跳轉到了B,如此循環往復…
返回值設爲false的情況(且刪去view.loadUrl()方法)就可解決這種問題。其實無論返回true還是false,只要爲WebView設置了WebViewClient,都不影響正常的加載功能,只是系統就不會再將url交給第三方的瀏覽器去處理了。
這兩種返回值的真正區別是這樣的:
shouldOverrideUrlLoading返回false,代表將url交給當前WebView加載,也就是正常的加載狀態;shouldOverrideUrlLoading返回true,代表開發者已經對url進行了處理,WebView就不會再對這個url進行加載了。可以用於屏蔽某些網址,藉此實現黑名單機制。
解決了用戶點擊回退鍵始終無法退出應用,但還存在一個顯著問題:用戶希望回退到上一級頁面,卻直接退出了app
回退問題解決方法:
goBack() //回退到上一級頁面
canGoBack()//能否回退到上一級頁面
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && wView.canGoBack()){
//如果按下返回鍵,同時又可以回退到上一級頁面,就返回上一級
wView.goBack();
return true;
}
return super.onKeyDown(keyCode,event);
}
默認情況下,返回鍵會執行finish()方法,結束當前Activity。
有些app爲了防止用戶誤觸,在按下返回鍵且無法回退上一級頁面時,會提示需要再次按下返回鍵,才結束當前Activity。這意味着需要在一定時間內連續按動兩次返回鍵纔可退出,設計更加人性化。將上述代碼改爲
private long exitTime = 0;
@Override
public void onBackPressed() {
if (wView.canGoBack()) {
wView.goBack();
} else {
if ((System.currentTimeMillis() - exitTime) > 2000) {
Toast.makeText(getApplicationContext(), "再按一次退出程序", Toast.LENGTH_SHORT).show();
exitTime = System.currentTimeMillis();
} else {
finish();
}
}
}
此外修改佈局文件,通過添加按鈕並編寫,也可以添加其他新功能,常用的有
finish(); //關閉當前Activity,一鍵退出
wView.reload(); //刷新當前頁面
wView.setScrollY(0); //滾動到頂部
添加進度條
public void onProgressChanged(WebView view, int newProgress){
super.onProgressChanged(view,newProgress);
}
newProgress*100,即可獲得當前加載的百分比,具體方法網上可查,這裏暫不深入
標題改爲當前網頁標題
public void onReceivedTitle(WebView view, String title) {
tTitle(title);
}
在開通Java權限後,可以設置網頁彈窗,至少有兩種方式,alert、confirm、prompt三種類型的彈窗
wView.loadUrl("javascript:alert('hello')");
wView.evaluateJavascript("javascript:alert('hello')",null);
放置位置如下:
wView.setWebViewClient(new WebViewClient() {
// @Override
// public boolean shouldOverrideUrlLoading(WebView view, String url) {
// return false;
// }
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
return false;
}
@Override
public void onPageFinished(WebView view, String url) {
//網頁加載完成時
super.onPageFinished(view, url);
//wView.loadUrl("javascript:alert('hello')"); // wView.evaluateJavascript("javascript:alert('hello')",null);
}
});