1.1 WebView概述
Android WebView在Android平臺上是一個特殊的View,它能用來顯示網頁,這個WebView類可以被用來在app中僅僅顯示一張在線的網頁,當然還可以用來開發瀏覽器,
WebView內部實作是采用渲染引擎(WebKit)來展示view的內容,提供網頁前進后退、網頁放大、縮小、搜索等功能,
WebView是一個基于WebKit引擎、展現Web頁面的控制元件,Android的WebView在低版本和高版本采用了不同的WebKit版本內核,
1.2 WebView的使用
1.2.1 WebView的基本使用
WebView的最簡單的使用方式即是直接顯示網頁內容,有以下兩個步驟:
- 在布局檔案中添加WebView控制元件;
- 在代碼中讓WebView控制元件加載顯示網頁,
下面我們直接講解使用WebView控制元件顯示百度首頁的網頁內容的案例:
首先,我們在布局檔案中來添加WebView控制元件,如下:
<WebView
android:id="@+id/wv_webview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
接著,我們需要在代碼中讓WebView控制元件加載顯示網頁,如下:
public class WebViewActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_web_view);
//獲得控制元件
WebView webView = (WebView) findViewById(R.id.wv_webview);
//訪問網頁
webView.loadUrl("http://www.baidu.com");
//系統默認會通過手機瀏覽器打開網頁,為了能夠直接通過WebView顯示網頁,則必須設定
webView.setWebViewClient(new WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
//使用WebView加載顯示url
view.loadUrl(url);
//回傳true
return true;
}
});
}
}
當然,在這里,我們需要加載網路上的資料內容,因此還需要添加網路權限:
<!-- 添加網路權限 -->
<uses-permission android:name="android.permission.INTERNET" />
運行顯示如下:

1.2.2 WebView使用詳解
一般來說,WebView不僅可以單獨使用,也可以聯合其子類一起使用,接下來我們也簡要了解一下:
- WebView的常見方法;
- WebView常用的子類 (WebSettings類、WebViewClient類、WebChromeClient類);
- WebView和JavaScript的互動,
1.2.2.1 Webview常用方法
- WebView的狀態
//激活WebView為活躍狀態,能正常執行網頁的回應
webView.onResume() ;
//當頁面被失去焦點被切換到后臺不可見狀態,需要執行onPause()
//通過onPause()動作通知內核暫停所有的動作,比如DOM的決議、JavaScript執行等
webView.onPause();
//當應用程式(存在webview)被切換到后臺時,這個方法不僅僅針對當前的webview而是全域的全應用程式的webview
//它會暫停所有webview的布局顯示、決議、延時,從而降低CPU功耗
webView.pauseTimers()
//恢復pauseTimers狀態
webView.resumeTimers();
//銷毀Webview //在關閉了Activity時,如果Webview的音樂或視頻,還在播放,就必須銷毀Webview,
//但是注意:webview呼叫destory時,webview仍系結在Activity上
//這是由于自定義webview構建時傳入了該Activity的context物件
//因此需要先從父容器中移除webview,然后再銷毀webview
rootLayout.removeView(webView);
webView.destroy();
- 前進、后退網頁
//是否可以后退
Webview.canGoBack()
//后退網頁
Webview.goBack()
//是否可以前進
Webview.canGoForward()
//前進網頁
Webview.goForward()
//以當前的index為起始點前進或者后退到歷史記錄中指定的steps
//如果steps為負數則為后退,正數則為前進
Webview.goBackOrForward(intsteps)
常見用法:Back鍵控制網頁后退
問題:當不做任何處理時,瀏覽網頁時,點擊系統的“Back”鍵,則使用WebView的整個Browser瀏覽器是會直接呼叫finish()而結束自身而關閉當前Activity并回傳到Home螢屏的(即直接出瀏覽器);
那么,在這里,我們可以做一些處理,讓點擊“Back”鍵后,讓網頁回傳上一頁而不是直接退出瀏覽器,
此時,我們就可以在當前Activity中處理該Back 事件,如下:
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KEYCODE_BACK) && mWebView.canGoBack()) {
mWebView.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
- 清除快取
//清除網頁訪問留下的快取
//由于內核快取是全域的因此這個方法不僅僅針對webview而是針對整個應用程式.
Webview.clearCache(true);
//清除當前webview訪問的歷史記錄
//只會webview訪問歷史記錄里的所有記錄除了當前訪問記錄
Webview.clearHistory();
//這個api僅僅清除自動完成填充的表單資料,并不會清除WebView存盤到本地的資料
Webview.clearFormData();
1.2.2.2 WebView常用的子類 (WebSettings類、WebViewClient類、WebChromeClient類)
WebView常用的子類主要有三個,分別是WebSettings類、WebViewClient類、WebChromeClient類,
- WebSettings類
作用:對WebView進行配置和管理;
配置步驟;
常見方法,
配置步驟:
第一步:添加訪問網路權限(AndroidManifest.xml)
<uses-permission android:name="android.permission.INTERNET"/>
第二步:生成一個WebView組件(有兩種方式)
//方式1:直接在在Activity中生成
WebView webView = new WebView(this);
//方法2:在Activity的layout檔案里添加webview控制元件
WebView webview = (WebView) findViewById(R.id.webView);
第三步:進行配置-利用WebSettings子類(常見方法)
//宣告WebSettings子類
WebSettings webSettings = webView.getSettings();
//如果訪問的頁面中要與Javascript互動,則webview必須設定支持Javascript
webSettings.setJavaScriptEnabled(true);
//支持插件
webSettings.setPluginsEnabled(true);
//設定自適應螢屏,兩者合用
webSettings.setUseWideViewPort(true); //將圖片調整到適合webview的大小
webSettings.setLoadWithOverviewMode(true); // 縮放至螢屏的大小
//縮放操作
webSettings.setSupportZoom(true); //支持縮放,默認為true,是下面那個的前提,
webSettings.setBuiltInZoomControls(true); //設定內置的縮放控制元件,若為false,則該WebView不可縮放
webSettings.setDisplayZoomControls(false); //隱藏原生的縮放控制元件
//其他細節操作
webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); //關閉webview中快取
webSettings.setAllowFileAccess(true); //設定可以訪問檔案
webSettings.setJavaScriptCanOpenWindowsAutomatically(true); //支持通過JS打開新視窗
webSettings.setLoadsImagesAutomatically(true); //支持自動加載圖片
webSettings.setDefaultTextEncodingName("utf-8");//設定編碼格式
常見方法:設定WebView快取
//優先使用快取
WebView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
//快取模式如下:
//LOAD_CACHE_ONLY: 不使用網路,只讀取本地快取資料
//LOAD_DEFAULT: (默認)根據cache-control決定是否從網路上取資料,
//LOAD_NO_CACHE: 不使用快取,只從網路獲取資料.
//LOAD_CACHE_ELSE_NETWORK,只要本地有,無論是否過期,或者no-cache,都使用快取中的資料
//不使用快取
WebView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
- WebViewClient類
作用:處理各種通知 & 請求事件
常見方法
常見方法:
shouldOverrideUrlLoading()
作用:打開網頁時,不呼叫系統瀏覽器進行打開,而是在本WebView中直接顯示,
//Webview控制元件
Webview webview = (WebView) findViewById(R.id.webView);
//加載一個網頁
webView.loadUrl("http://www.google.com/");
//重寫shouldOverrideUrlLoading()方法,使得打開網頁時不呼叫系統瀏覽器, 而是在本WebView中顯示
webView.setWebViewClient(new WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
});
onPageStarted()
作用:開始載入頁面時呼叫此方法,在這里我們可以設定一個loading的頁面,告訴用戶程式正在等待網路回應,
webView.setWebViewClient(new WebViewClient(){
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
//設定加載開始的操作
}
});
onPageFinished()
作用:在頁面加載結束時呼叫,我們可以關閉loading 條,切換程式動作,
webView.setWebViewClient(new WebViewClient(){
@Override
public void onPageFinished(WebView view, String url) {
//設定加載結束的操作
}
});
onLoadResource()
作用:在加載頁面資源時會呼叫,每一個資源(比如圖片)的加載都會呼叫一次,
webView.setWebViewClient(new WebViewClient(){
@Override
public boolean onl oadResource(WebView view, String url) {
//設定加載資源的操作
}
});
onReceivedError()
作用:加載頁面的服務器出現錯誤時(如404)呼叫,
App里面使用webview控制元件的時候遇到了諸如404這類的錯誤的時候,若也顯示瀏覽器里面的那種錯誤提示頁面就顯得很丑陋了,那么這個時候我們的app就需要加載一個本地的錯誤提示頁面,即webview如何加載一個本地的頁面
//步驟1:寫一個html檔案(error_handle.html),用于出錯時展示給用戶看的提示頁面
//步驟2:將該html檔案放置到代碼根目錄的assets檔案夾下
//步驟3:復寫WebViewClient的onRecievedError方法 //該方法傳回了錯誤碼,根據錯誤型別可以進行不同的錯誤分類處理
webView.setWebViewClient(new WebViewClient(){
@Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl){
switch(errorCode) {
case HttpStatus.SC_NOT_FOUND:
view.loadUrl("file:///android_assets/error_handle.html");
break;
}
}
});
onReceivedSslError()
作用:處理https請求
webView默認是不處理https請求的,頁面顯示空白
webView.setWebViewClient(new WebViewClient() {
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
handler.proceed(); //表示等待證書回應
// handler.cancel(); //表示掛起連接,為默認方式
// handler.handleMessage(null); //可做其他處理
}
});
- WebChromeClient類
作用:輔助 WebView 處理 Javascript 的對話框,網站圖示,網站標題等等,
常見方法
常見方法:
onProgressChanged()
作用:獲得網頁的加載進度并顯示
webview.setWebChromeClient(new WebChromeClient(){
@Override
public void onProgressChanged(WebView view, int newProgress) {
if (newProgress < 100) {
String progress = newProgress + "%";
progress.setText(progress);
} else {
progress.setText(“100%”);
}
});
onReceivedTitle()
作用:獲取Web頁中的標題
每個網頁的頁面都有一個標題,比如www.baidu.com這個頁面的標題即“百度一下,你就知道”,那么如何知道當前webview正在加載的頁面的title并進行設定呢?
webview.setWebChromeClient(new WebChromeClient(){
@Override
public void onReceivedTitle(WebView view, String title) {
titleview.setText(title);
}
1.2.2.3 WebView和JavaScript的互動
注意事項:如何避免WebView記憶體泄露?
建議不要在xml布局檔案中getApplicationgContext()定義Webview控制元件 ,而是在需要的時候在Activity中直接創建,并且Context背景關系物件推薦使用
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
webView = new WebView(getApplicationContext());
webView.setLayoutParams(params);
mLayout.addView(webView);
在Activity銷毀(WebView)時,先讓WebView加載null內容,然后移除WebView,再銷毀WebView,最后把WebView設定為null,
@Override
protected void onDestroy() {
if (webView != null) {
webView.loadDataWithBaseURL(null, "", "text/html", "utf-8", null);
webView.clearHistory(); ((ViewGroup)
webView.getParent()).removeView(mWebView);
webView.destroy();
webView = null;
}
super.onDestroy();
}
實體:
目標:實作顯示“www.baidu.com”,并獲取標題、開始加載提示、獲取加載進度和結束加載提示,
具體實作
運行顯示如下:

步驟一:在AndroidManifest.xml清單檔案中添加網路權限
<uses-permission android:name="android.permission.INTERNET"/>
步驟二:布局檔案
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="獲取標題" />
<TextView
android:id="@+id/tv_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_marginTop="10dp"
android:text="開始加載提示" />
<TextView
android:id="@+id/tv_progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="獲取加載進度" />
<TextView
android:id="@+id/tv_end"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_marginTop="10dp"
android:text="結束加載提示" />
<WebView
android:id="@+id/wv_webview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
步驟三:根據需要實作的功能,呼叫使用相應的子類及其方法
public class WebViewActivity extends AppCompatActivity {
private WebView webView;
private TextView tvTitle;
private TextView tvStart;
private TextView tvProgress;
private TextView tvEnd;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_web_view);
//獲得控制元件
webView = (WebView) findViewById(R.id.wv_webview);
//獲得其他控制元件
tvTitle = (TextView) findViewById(R.id.tv_title);
tvStart = (TextView) findViewById(R.id.tv_start);
tvProgress = (TextView) findViewById(R.id.tv_progress);
tvEnd = (TextView) findViewById(R.id.tv_end);
//訪問網頁
webView.loadUrl("http://www.baidu.com");
//系統默認會通過手機瀏覽器打開網頁,為了能夠直接通過WebView顯示網頁,則必須設定
//設定WebViewClient
webView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
//使用WebView加載顯示url
view.loadUrl(url);
//回傳true
return true;
}
//加載前
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
tvStart.setText("開始加載!!");
}
//加載完成
@Override
public void onPageFinished(WebView view, String url) {
tvEnd.setText("加載完成...");
}
});
//設定WebChromeClient類
webView.setWebChromeClient(new WebChromeClient() {
//獲取網站標題
@Override
public void onReceivedTitle(WebView view, String title) {
tvTitle.setText(title);
}
//進度顯示
@Override
public void onProgressChanged(WebView view, int newProgress) {
if (newProgress < 100) {
tvProgress.setText(newProgress + "%");
} else {
tvProgress.setText("100%");
}
}
});
}
//點擊回傳上一頁面而不是退出瀏覽器
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && webView.canGoBack()) {
webView.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
//銷毀Webview
@Override
protected void onDestroy() {
if (webView != null) {
webView.loadDataWithBaseURL(null, "", "text/html", "utf-8", null);
webView.clearHistory();
((ViewGroup) webView.getParent()).removeView(webView);
webView.destroy();
webView = null;
}
super.onDestroy();
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/272417.html
標籤:嵌入式
上一篇:關于記憶體重映射同步的問題
