隨着Html5的快速發展,越來越多的App對WebView的使用越來越頻繁,不再像以前一樣只需要調用
webview.loadurl(url)
就可以滿足基本的使用,本文就對目前WebView的常用用法進行總結介紹,希望能幫到一些小夥伴…
1. WebView是個什麼鬼
一個用來展示web界面的View, WebView可以在自己的瀏覽器或者Activity中進行內容展示,採用了WebKit渲染引擎來顯示網頁,包括歷史導航,前一頁,後一頁,放大,縮小,執行搜索文本等功能;如果你想在項目中使用WebView,需要添加一個訪問網絡的權限:
uses-permission android:name=”android.permission.INTERNET”
2. WebView的基本使用
2.1 發送Intent調用系統瀏覽器打開加載頁
WebView在默認情況下,不支持瀏覽器中例如widget插件,默認關閉Js交互,並忽略網頁上將被忽略;如果你只想展示一個頁面,但是並不需要交互,那使用webview是比較合適的; 如果你想實現一個全面的web頁面,那麼你可以開啓一個URL意圖來使用瀏覽器打開當前URL,但一般爲了用戶體驗,這種用法的使用還是比較少的;示例如下
Uri uri = Uri.parse("http://www.baidu.com");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
2.2 調用webview.loadUrl(url)來加載
2.2.1 webview.loadUrl(url)加載網絡地址
當然,多數情況下,我們會在layout文件中定義一個webview控件,然後在Activity中的onCreate裏面加載我們想要看到的url界面,使用如下:
//第一種寫法,常用格式
WebView webView = (WebView) findViewById(R.id.webview);
webView.loadUrl("http://www.baidu.com");
//注意:如果不想彈出系統瀏覽器進行界面顯示,需要重寫該方法
webView.setWebViewClient(new WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
//返回值沒有關係
return super.shouldOverrideUrlLoading(view,url);
}
});
//第二種寫法,直接在setContentView中傳入webview
WebView webView = new WebView(this);
webView.loadUrl("http://www.baidu.com");
setContentView(webView);
webView.setWebViewClient(new WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
//返回值沒有關係
return super.shouldOverrideUrlLoading(view,url);
}
});
注意:如果不想彈出系統瀏覽器進行界面顯示,需要重寫shouldOverrideUrlLoading方法
2.2.2 webview.loadUrl(url)加載apk包內html文件
webview不但可以加載網絡頁面,也可以加載apk包下的html文件,將html文件放在項目assets資源目錄下,然後調用以下代碼即可
webView.loadUrl("file:///android_asset/test.html");
2.2.3 webview.loadUrl(url)加載SD卡下的html文件
webview加載SD卡根目錄下test.html文件代碼如下:
webView.loadUrl("content://com.android.htmlfileprovider/sdcard/test.html");
2.3 webview加載HTML格式字符串
除了可以加載網頁之外,webview也可以加載HTML格式的字符串;主要是兩個方法,一個webView.loadData(data,mimeType,encoding);
來展示,一個是webView.loadDataWithBaseURL(baseUrl,data,mimeType,encoding,historyUrl);
. 如果是帶有中文的數據,默認顯示會展示亂碼,可以有兩種方式來解決亂碼;我們先來看一下如果都是英文數據該如何展示:
String data = "<html><body>You scored <b>Egglish</b> points.</body></html>";
webView.loadData(summary, "text/html", null);
展示效果如圖所示:
如果包含了中文,會顯示亂碼:
第一種修改方式,可以在loadData中更改第二個參數,注意:如果將第三個參數更改爲”UTF-8”,依然會是亂碼;正確修改如下:
String data = "<html><body>You scored <b>中文測試</b> points.</body></html>";
webView.loadData(data, "text/html; charset=UTF-8", null);
顯示效果如下:
原因如下:
如果用
loadDataWithBaseURL
時,如果不傳入URL時,刷新會造成白屏,因爲刷新時調用的的是reload方法,reload是根據傳入的URL進行一次重新加載即再次loadUrl(url),不傳入URL時,默認的的URL是about:blank;使用loadData,刷新只是從緩存裏面取,但是在4.0以上的,如果按照API裏所寫的loadData(data, “UTF-8”, null);
時會亂碼,如果寫成loadData(data, "text/html; charset=UTF-8", null);
loadData最終的機制是會把傳入的三個參數拼接在一起,然後再進行loadUrl操作,參數就是data, "text/html; charset=UTF-8", null
這三個進行拼裝,加入text/html; charset=UTF-8
就相當於限定了頁面的字符
上面的一種修改方式可以適配大多數機型,但依然有少部分機型會顯示亂碼,可能與系統底層文件修改有關,所以就有了另一種修改方式,調用loadDataWithBaseURL方法,修改如下:
String data = "<html><body>You scored <b>中文測試</b> points.</body></html>";
webView.loadDataWithBaseURL(null,summary,"text/html","UTF-8",null);
3. 自定義你的webview
WebView除了基本的用法以外,還可以進行自定義來達到你想要的效果,比如創建一個匿名WebChromeClient來輔助WebView處理Javascript的對話框,網站圖標,網站title,加載進度等;也可以創建一個匿名WebViewClient ,來幫助WebView處理各種通知、請求事件等;當然,也可以啓用 WebSettings,來開啓Js交互等等,下面我們就來逐一介紹.
3.1 WebChromeClient
方法中的代碼均有Android端自行處理,實現方式可以寫一個匿名內部類,或者寫一個WebChromeClient類,然後調用webview.setWebChromeClient(mWebChromeClient);代碼示例如下:
webView.setWebChromeClient(new WebChromeClient() {
//獲取網頁的加載進度,因有的網頁是採用分模塊加載,所以進度值並非只是一次1~100;可以爲: 29~100;30~100;
@Override
public void onProgressChanged(WebView view, int progress) {
Log.e(TAG,"progress="+progress);
}
//獲取當前網頁中的Title值來設置給自己的title
//注意:如果無網,獲取的 title= 找不到網頁
//所以開發者可以在接受到onReceiveError的回調後,不要在使用當前獲取的title值了
@Override
public void onReceivedTitle(WebView view, String title) {
Log.e(TAG,"title="+title);
}
//獲取當前網頁的icon,拿到後,會獲取一個Bitmap對象,你想幹嘛就幹嘛
@Override
public void onReceivedIcon(WebView view, Bitmap icon) {
super.onReceivedIcon(view, icon);
}
});
以上爲簡單用法,下面我們對 onJsAlert()
, onJsPrompt()
,onJsConfirm()
進行逐一分析;在WebChromeClient類裏可以重寫這三個方法,此時WebView中加載的html中如果執行alert("alert....");
, confirm("confirm...");
, prompt("prompt...", "defaultValue");
這三個方法,該類就會監聽到執行對應的三個方法。我們可以讓這三個方法的返回值爲true ,即自定義此方法。在裏面寫入自己定義的Dialog,便可實現html與Activity交互。
注意 JsResult 此類需要在操作時,如果操作則 result.cofirm(). 取消則 result.cancel(); 還必須這每一個方法中寫入 dialog.setOnkeyListener(); 方法來監聽Back鍵,listener中 要寫 result.cancel(); 否則系統沒有消費這個事件,會出錯。
3.1.1 自定義onJsAlert
什麼是Javascript Alert?
Alert是一種提示信息或者警告信息的對話框,一旦顯示到用戶面前,只能點擊OK才能關閉.
通常一般的實現類似:
<html>
<SCRIPT type="text/javascript">
alert('This is alert dialog !')
</SCRIPT>
</html>
效果圖如下:
onJsAlert API 介紹:
public boolean onJsAlert (WebView view, String url, String message, JsResult result)
Tell the client to display a javascript alert dialog. If the client returns true, WebView will assume that the client will handle the dialog. If the client returns false, it will continue execution.
告知客戶端將顯示一個alert dialog; 如果方法返回了true, 那麼webview就會來自行處理這個dialog; 如果返回了false,則會繼續執行下去,webview不進行處理;
在Android中,我們一般重寫onJsAlert
方法,會將參數中的message信息用Toast的形式彈出以告知用戶,代碼如下;
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show();
////因爲沒有綁定事件,需要強行confirm,否則頁面會變黑顯示不了內容。
result.confirm();
return true;
}
或者我們可以自行彈出一個Dialog,覆蓋默認的顯示界面,代碼如下:
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
final AlertDialog.Builder builder = new AlertDialog.Builder(view
.getContext());
builder.setTitle("測試自定義對話框").setMessage(message)
.setPositiveButton("確定", null);
//這裏不需要綁定按鍵事件
//可自行屏蔽keycode按鍵
builder.setOnKeyListener(new DialogInterface.OnKeyListener() {
@Override
public boolean onKey(DialogInterface dialog, int keyCode,
KeyEvent event) {
Log.e(TAG,"keyCode==" + keyCode + "event=" + event);
return true;
}
});
//禁止響應按back鍵的事件
builder.setCancelable(false);
AlertDialog dialog = builder.create();
dialog.show();
result.confirm();//因爲沒有綁定事件,需要強行confirm,否則頁面會變黑顯示不了內容。
return true;
}
3.1.2 自定義onJsConfirm
用法與onJsAlert
基本一樣,直接上代碼:
@Override
public boolean onJsConfirm(WebView view, String url, String message,
final JsResult result) {
final AlertDialog.Builder builder = new AlertDialog.Builder(view
.getContext());
builder.setTitle("webview測試confirm對話框")
.setMessage(message)
.setPositiveButton("確定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
result.confirm();
}
})
.setNeutralButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
result.cancel();
}
});
builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
result.cancel();
}
});
//屏蔽keycode的按鍵,避免按鍵後導致對話框消息而頁面無法再彈出對話框的問題
builder.setOnKeyListener(new DialogInterface.OnKeyListener() {
@Override
public boolean onKey(DialogInterface dialog, int keyCode,
KeyEvent event) {
Log.e(TAG, "keyCode==" + keyCode + "event=" + event);
return true;
}
});
//禁止響應按back鍵的事件
builder.setCancelable(false);
AlertDialog dialog = builder.create();
dialog.show();
return true;
}
3.1.3 自定義 onJsPrompt
直接上代碼,大致用法一樣,只不過個別參數不同:
@Override
public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, final JsPromptResult result) {
final AlertDialog.Builder builder = new AlertDialog.Builder(view
.getContext());
builder.setTitle("webview測試prompt對話框").setMessage(message);
final EditText et = new EditText(view.getContext());
et.setSingleLine();
et.setText(defaultValue);
builder.setView(et);
builder.setPositiveButton("確定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
result.confirm(et.getText().toString());
}
}).setNeutralButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
result.cancel();
}
});
//屏蔽keycode按鍵,避免按鍵後導致對話框消息而頁面無法再彈出對話框的問題
builder.setOnKeyListener(new DialogInterface.OnKeyListener() {
@Override
public boolean onKey(DialogInterface dialog, int keyCode,
KeyEvent event) {
Log.e(TAG, "keyCode==" + keyCode + "event=" + event);
return true;
}
});
//禁止響應按back鍵的事件
builder.setCancelable(false);
AlertDialog dialog = builder.create();
dialog.show();
return true;
}
4. 使用websettings讓你的webview更加強大
webview獲取到websettings之後,可以對當前的webview進行各種設置,如 Js交互開啓,縮放,支持插件等等,我們直接以代碼爲例,代碼中對每個功能點都進行了詳細說明,請小夥伴參閱;
WebSettings webSettings = webView.getSettings();
//支持獲取手勢焦點,輸入用戶名、密碼或其他
webView.requestFocusFromTouch();
//支持js交互
webSettings.setJavaScriptEnabled(true);
webSettings.setJavaScriptCanOpenWindowsAutomatically(true); //支持通過JS打開新窗口
//設置自適應屏幕,需要與setLoadWithOverviewMode合用
webSettings.setUseWideViewPort(true); //可以將圖片調整到適合webview的大小
webSettings.setLoadWithOverviewMode(true); // 縮放至屏幕的大小
//支持縮放,默認爲true。是setBuiltInZoomControls的前提。
//若setSupportZoom是false,則該WebView不可縮放,這個不管setBuiltInZoomControls設置什麼都不能縮放。
webSettings.setSupportZoom(true);
webSettings.setBuiltInZoomControls(true); //設置內置的縮放控件
webSettings.setDisplayZoomControls(false); //隱藏原生的縮放控件
//提高渲染的優先級
webSettings.setRenderPriority(WebSettings.RenderPriority.HIGH);
webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN); //支持內容重新佈局
webSettings.supportMultipleWindows(); //支持多窗口
webSettings.setAllowFileAccess(true); //設置可以訪問文件
webSettings.setLoadsImagesAutomatically(true); //支持自動加載圖片
webSettings.setDefaultTextEncodingName("utf-8");//設置編碼格式
好了,上面就是webview的一些簡單用法,後面我們將對webview的緩存機制,前進回退操作,與js互調,避免webview內存泄露等問題進行逐一分析,希望我的文字能在你需要的時候幫到你, 願大家有美好的一天…..