轉(zhuǎn)載請注明出處:
http://blog.csdn.net/lowprofile_coding/article/details/77928614
WebView介紹
Android WebView在Android平臺上是一個特殊的View橄仆, 基于webkit引擎、展現(xiàn)web頁面的控件衅斩,這個類可以被用來在你的app中僅僅顯示一張?jiān)诰€的網(wǎng)頁盆顾,還可以用來開發(fā)瀏覽器。WebView內(nèi)部實(shí)現(xiàn)是采用渲染引擎來展示view的內(nèi)容畏梆,提供網(wǎng)頁前進(jìn)后退您宪,網(wǎng)頁放大奈懒,縮小,搜索宪巨。Android的Webview在低版本和高版本采用了不同的webkit版本內(nèi)核磷杏,4.4后直接使用了Chrome。
現(xiàn)在很多APP都內(nèi)置了Web網(wǎng)頁捏卓,比如說很多電商平臺极祸,淘寶、京東怠晴、聚劃算等等贿肩。WebView比較靈活,不需要升級客戶端龄寞,只需要修改網(wǎng)頁代碼即可。一些經(jīng)常變化的頁面可以用WebView這種方式去加載網(wǎng)頁汤功。例如中秋節(jié)跟國慶節(jié)打開的頁面不一樣物邑,如果是用WebView顯示的話,只修改修改html頁面就行滔金,而不需要升級客戶端色解。
Webview功能強(qiáng)大,可以直接使用html文件(本地sdcard/assets目錄)餐茵,還可以直接加載url科阎,使用JavaScript可以html跟原生APP互調(diào)。
加載html四種方式
webView.loadUrl("http://139.196.35.30:8080/OkHttpTest/apppackage/test.html");//加載url
webView.loadUrl("file:///android_asset/test.html");//加載asset文件夾下html
//方式3:加載手機(jī)sdcard上的html頁面
webView.loadUrl("content://com.ansen.webview/sdcard/test.html");
//方式4 使用webview顯示html代碼
webView.loadDataWithBaseURL(null,"<html><head><title> 歡迎您 </title></head>" +
"<body><h2>使用webview顯示 html代碼</h2></body></html>", "text/html" , "utf-8", null);
WebViewClient與WebChromeClient區(qū)別
使用WebView基本都會使用這兩個類忿族,那他們有哪些區(qū)別呢锣笨?
WebViewClient主要幫助WebView處理各種通知、請求事件的道批,有以下常用方法:
- onPageFinished 頁面請求完成
- onPageStarted 頁面開始加載
- shouldOverrideUrlLoading 攔截url
- onReceivedError 訪問錯誤時回調(diào)错英,例如訪問網(wǎng)頁時報(bào)錯404隆豹,在這個方法回調(diào)的時候可以加載錯誤頁面。
WebChromeClient主要輔助WebView處理Javascript的對話框璃赡、網(wǎng)站圖標(biāo)判哥、網(wǎng)站title碉考、加載進(jìn)度等,有以下常用方法侯谁。
- onJsAlert webview不支持js的alert彈窗瞒渠,需要自己監(jiān)聽然后通過dialog彈窗
- onReceivedTitle 獲取網(wǎng)頁標(biāo)題
- onReceivedIcon 獲取網(wǎng)頁icon
- onProgressChanged 加載進(jìn)度回調(diào)
簡單使用
因?yàn)樾枰虞d網(wǎng)頁url,所以需要在AndroidManifest.xml中添加訪問網(wǎng)絡(luò)權(quán)限技扼。
<uses-permission android:name="android.permission.INTERNET" />
布局文件:activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<WebView
android:id="@+id/webview"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<ProgressBar
android:id="@+id/progressbar"
style="@android:style/Widget.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="3dip"
android:max="100"
android:progress="0"
android:visibility="gone"/>
</FrameLayout>
外層FrameLayout伍玖,里面有WebView跟ProgressBar,WebView的寬高匹配父類剿吻,ProgressBar橫向進(jìn)度條窍箍,高度3dip,按照FrameLayout布局規(guī)則丽旅,ProgressBar會覆蓋在WebView之上椰棘,默認(rèn)是隱藏不顯示。
MainActivity.java
public class MainActivity extends AppCompatActivity {
private WebView webView;
private ProgressBar progressBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
progressBar= (ProgressBar)findViewById(R.id.progressbar);//進(jìn)度條
webView = (WebView) findViewById(R.id.webview);
// webView.loadUrl("file:///android_asset/test.html");//加載asset文件夾下html
webView.loadUrl("http://139.196.35.30:8080/OkHttpTest/apppackage/test.html");//加載url
//使用webview顯示html代碼
// webView.loadDataWithBaseURL(null,"<html><head><title> 歡迎您 </title></head>" +
// "<body><h2>使用webview顯示 html代碼</h2></body></html>", "text/html" , "utf-8", null);
webView.addJavascriptInterface(this,"android");//添加js監(jiān)聽 這樣html就能調(diào)用客戶端
webView.setWebChromeClient(webChromeClient);
webView.setWebViewClient(webViewClient);
WebSettings webSettings=webView.getSettings();
webSettings.setJavaScriptEnabled(true);//允許使用js
/**
* LOAD_CACHE_ONLY: 不使用網(wǎng)絡(luò)榄笙,只讀取本地緩存數(shù)據(jù)
* LOAD_DEFAULT: (默認(rèn))根據(jù)cache-control決定是否從網(wǎng)絡(luò)上取數(shù)據(jù)邪狞。
* LOAD_NO_CACHE: 不使用緩存,只從網(wǎng)絡(luò)獲取數(shù)據(jù).
* LOAD_CACHE_ELSE_NETWORK茅撞,只要本地有帆卓,無論是否過期,或者no-cache米丘,都使用緩存中的數(shù)據(jù)剑令。
*/
webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);//不使用緩存,只從網(wǎng)絡(luò)獲取數(shù)據(jù).
//支持屏幕縮放
webSettings.setSupportZoom(true);
webSettings.setBuiltInZoomControls(true);
//不顯示webview縮放按鈕
// webSettings.setDisplayZoomControls(false);
}
//WebViewClient主要幫助WebView處理各種通知拄查、請求事件
private WebViewClient webViewClient=new WebViewClient(){
@Override
public void onPageFinished(WebView view, String url) {//頁面加載完成
progressBar.setVisibility(View.GONE);
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {//頁面開始加載
progressBar.setVisibility(View.VISIBLE);
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
Log.i("ansen","攔截url:"+url);
if(url.equals("http://www.google.com/")){
Toast.makeText(MainActivity.this,"國內(nèi)不能訪問google,攔截該url",Toast.LENGTH_LONG).show();
return true;//表示我已經(jīng)處理過了
}
return super.shouldOverrideUrlLoading(view, url);
}
};
//WebChromeClient主要輔助WebView處理Javascript的對話框吁津、網(wǎng)站圖標(biāo)、網(wǎng)站title堕扶、加載進(jìn)度等
private WebChromeClient webChromeClient=new WebChromeClient(){
//不支持js的alert彈窗碍脏,需要自己監(jiān)聽然后通過dialog彈窗
@Override
public boolean onJsAlert(WebView webView, String url, String message, JsResult result) {
AlertDialog.Builder localBuilder = new AlertDialog.Builder(webView.getContext());
localBuilder.setMessage(message).setPositiveButton("確定",null);
localBuilder.setCancelable(false);
localBuilder.create().show();
//注意:
//必須要這一句代碼:result.confirm()表示:
//處理結(jié)果為確定狀態(tài)同時喚醒WebCore線程
//否則不能繼續(xù)點(diǎn)擊按鈕
result.confirm();
return true;
}
//獲取網(wǎng)頁標(biāo)題
@Override
public void onReceivedTitle(WebView view, String title) {
super.onReceivedTitle(view, title);
Log.i("ansen","網(wǎng)頁標(biāo)題:"+title);
}
//加載進(jìn)度回調(diào)
@Override
public void onProgressChanged(WebView view, int newProgress) {
progressBar.setProgress(newProgress);
}
};
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
Log.i("ansen","是否有上一個頁面:"+webView.canGoBack());
if (webView.canGoBack() && keyCode == KeyEvent.KEYCODE_BACK){//點(diǎn)擊返回按鈕的時候判斷有沒有上一頁
webView.goBack(); // goBack()表示返回webView的上一頁面
return true;
}
return super.onKeyDown(keyCode,event);
}
/**
* JS調(diào)用android的方法
* @param str
* @return
*/
@JavascriptInterface //仍然必不可少
public void getClient(String str){
Log.i("ansen","html調(diào)用客戶端:"+str);
}
@Override
protected void onDestroy() {
super.onDestroy();
//釋放資源
webView.destroy();
webView=null;
}
}
- onCreate 查找控件,給webView設(shè)置加載url稍算,添加js監(jiān)聽潮酒,監(jiān)聽的名稱是"android",設(shè)置webChromeClient跟webViewClient回調(diào),通過getSettings方法獲取WebSettings對象邪蛔,設(shè)置允許加載js急黎,設(shè)置緩存模式,支持縮放侧到。
- webViewClient 重寫了幾個方法,onPageFinished頁面加載完成隱藏進(jìn)度條勃教,onPageStarted頁面開始加載顯示進(jìn)度條,shouldOverrideUrlLoading攔截url匠抗,如果請求url是打開google故源,不讓他請求,因?yàn)間oogle在國內(nèi)不能訪問汞贸,就算請求也請求不到還不如攔截掉绳军,直接告訴用戶不能訪問印机。
- webChromeClient onJsAlert()因?yàn)閃ebView不支持alert彈窗门驾,在這個方法中用AlertDialog去彈窗。onReceivedTitle獲取網(wǎng)頁標(biāo)題楣责。onProgressChanged頁面加載進(jìn)度,把加載進(jìn)度給progressBar秆麸。
- onKeyDown 如果點(diǎn)擊系統(tǒng)自帶返回鍵&&webView有上一級頁面及汉,調(diào)用goBack返回。否則不處理房铭。什么時候輝有上一級頁面呢?就是你從首頁跳轉(zhuǎn)到了一個新頁面,點(diǎn)擊返回的時候會返回首頁。如果本來就在首頁點(diǎn)擊返回的時候會退出app迅脐。
- getClient html頁面的JS可以通過這個方法回調(diào)原生APP,這個方法有個注解@JavascriptInterface豌骏,這個是必須的,這個方法有個字符串參數(shù)窃躲,這個方法跟我們在onCreate中調(diào)用addJavascriptInterface傳入的name一起使用的钦睡。例如html中想要回調(diào)這個方法可以這樣寫:javascript:android.getClient("傳一個字符串給客戶端");
- onDestroy activity銷毀時釋放webView資源。
運(yùn)行代碼洒琢,效果圖如下:
Android開發(fā)666 - 安卓開發(fā)技術(shù)分享
掃描二維碼加關(guān)注