Android及iOS的webview的引擎都是webkit,對H5提供支持.
WebView可以使得網頁輕鬆的內嵌到app裏,還可以直接跟js相互調用。
webview有兩個方法:setWebChromeClient 和 setWebClient
setWebClient:主要處理解析,渲染網頁等瀏覽器做的事情
setWebChromeClient:輔助WebView處理Javascript的對話框,網站圖標,網站title,加載進度等
WebViewClient就是幫助WebView處理各種通知、請求事件的。
一. webview組件如何使用
- 添加權限:AndroidManifest.xml中必須使用許可”android.permission.INTERNET”,否則會出Web page not available錯誤。
- 在Activity中生成一個WebView組件:WebView webView = new WebView(this);或者可以在activity的layout文件裏添加webview控件:
- WebSettings 的常用方法介紹
setPluginsEnabled(true); //支持插件
setUseWideViewPort(false); //將圖片調整到適合webview的大小
setSupportZoom(true); //支持縮放
setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN); //支持內容重新佈局
supportMultipleWindows(); //多窗口
setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); //關閉webview中緩存
setAllowFileAccess(true); //設置可以訪問文件
setNeedInitialFocus(true); //當webview調用requestFocus時爲webview設置節點
webview webSettings.setBuiltInZoomControls(true); //設置支持縮放
setJavaScriptCanOpenWindowsAutomatically(true); //支持通過JS打開新窗口
setLoadWithOverviewMode(true); // 縮放至屏幕的大小
setLoadsImagesAutomatically(true); //支持自動加載圖片
- WebViewClient 的方法全解
doUpdateVisitedHistory(WebView view, String url, boolean isReload) //(更新歷史記錄)
onFormResubmission(WebView view, Message dontResend, Message resend) //(應用程序重新請求網頁數據)
onLoadResource(WebView view, String url) // 在加載頁面資源時會調用,每一個資源(比如圖片)的加載都會調用一次。
onPageStarted(WebView view, String url, Bitmap favicon) //這個事件就是開始載入頁面調用的,通常我們可以在這設定一個loading的頁面,告訴用戶程序在等待網絡響應。
onPageFinished(WebView view, String url) //在頁面加載結束時調用。同樣道理,我們知道一個頁面載入完成,於是我們可以關閉loading 條,切換程序動作。
onReceivedError(WebView view, int errorCode, String description, String failingUrl)// (報告錯誤信息)
onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host,String realm)//(獲取返回信息授權請求)
onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) //重寫此方法可以讓webview處理https請求。
onScaleChanged(WebView view, float oldScale, float newScale) // (WebView發生改變時調用)
onUnhandledKeyEvent(WebView view, KeyEvent event) //(Key事件未被加載時調用)
shouldOverrideKeyEvent(WebView view, KeyEvent event)//重寫此方法才能夠處理在瀏覽器中的按鍵事件。
shouldOverrideUrlLoading(WebView view, String url) //在點擊請求的是鏈接是纔會調用,重寫此方法返回true表明點擊網頁裏面的鏈接還是在當前的webview裏跳轉,不跳到瀏覽器那邊
① 設置WevView要顯示的網頁:
互聯網用:webView.loadUrl(“http://www.google.com“);
本地文件用:webView.loadUrl(“file:///android_asset/XX.html”); 本地文件存放在:assets文件中
② 如果希望點擊鏈接由自己處理,而不是新開Android的系統browser中響應該鏈接。給WebView添加一個事件監聽對象(WebViewClient)並重寫其中的一些方法:
shouldOverrideUrlLoading:對網頁中超鏈接按鈕的響應。當按下某個連接時WebViewClient會調用這個方法,並傳遞參數:按下的url。比如當webview內嵌網頁的某個數字被點擊時,它會自動認爲這是一個電話請求,會傳遞url:tel:123,如果你不希望如此可通過重寫shouldOverrideUrlLoading函數解決:
public boolean shouldOverrideUrlLoading(WebView view,String url){
if(url.indexOf("tel:")<0){//頁面上有數字會導致連接電話
view.loadUrl(url); //在當前的webview中跳轉到新的url
}
return true;
}
③ 處理https請求
webView默認是不處理https請求的,頁面顯示空白,需要進行如下設置:
webView.setWebViewClient(new WebViewClient() {
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
handler.proceed();
// handler.cancel();
// handler.handleMessage(null);
}
});
onReceivedSslError爲webView處理ssl證書設置
其中handler.proceed();表示等待證書響應
handler.cancel();表示掛起連接,爲默認方式
handler.handleMessage(null);可做其他處理
另外還有其他一些可重寫的方法
-接收到Http請求的事件
onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, String realm)
-打開鏈接前的事件
public boolean shouldOverrideUrlLoading(WebView view, String url) { view.loadUrl(url); return true; }
這個函數我們可以做很多操作,比如我們讀取到某些特殊的URL,於是就可以不打開地址,取消這個操作,進行預先定義的其他操作,這對一個程序是非常必要的。
-載入頁面完成的事件
public void onPageFinished(WebView view, String url){ }
同樣道理,我們知道一個頁面載入完成,於是我們可以關閉loading條,切換程序動作。
-載入頁面開始的事件
public void onPageStarted(WebView view, String url, Bitmap favicon) { }
這個事件就是開始載入頁面調用的,通常我們可以在這設定一個loading的頁面,告訴用戶程序在等待網絡響應。
通過這幾個事件,我們可以很輕鬆的控制程序操作,一邊用着瀏覽器顯示內容,一邊監控着用戶操作實現我們需要的各種顯示方式,同時可以防止用戶產生誤操作。
④ 如果用webview點鏈接看了很多頁以後,如果不做任何處理,點擊系統“Back”鍵,整個瀏覽器會調用finish()而結束自身,如果希望瀏覽的網頁回退而不是退出瀏覽器,需要在當前Activity中處理並消費掉該Back事件。
覆蓋Activity類的onKeyDown(int keyCoder,KeyEvent event)方法。
//改寫物理按鍵——返回的邏輯
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
if(keyCode==KeyEvent.KEYCODE_BACK)
{
if(webView.canGoBack())
{
webView.goBack();//返回上一頁面
return true;
}
else
{
System.exit(0);//退出程序
}
}
return super.onKeyDown(keyCode, event);
}
- 使用緩存
優先使用緩存
webView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
不使用緩存:
webView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
- 監聽webview的滾動事件
監聽webview的滾動事件,至少需要獲得兩個方面的信息:
1.滾動的偏移量 2.滾動的方向
但是WebView並沒有對外提供一個類似於setOnScrollChangedListener之類的監聽者,只有一個如下的protected方法:
protected void onScrollChanged(final int l, final int t, final int oldl, final int oldt) {}
所以我們可以自定義一個
import android.content.Context;
import android.util.AttributeSet;
import android.webkit.WebView;
public class ObservableWebView extends WebView {
private OnScrollChangedCallback mOnScrollChangedCallback;
public ObservableWebView(final Context context) {
super(context);
}
public ObservableWebView(final Context context, final AttributeSet attrs) {
super(context, attrs);
}
public ObservableWebView(final Context context, final AttributeSet attrs,
final int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onScrollChanged(final int l, final int t, final int oldl,
final int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
if (mOnScrollChangedCallback != null) {
mOnScrollChangedCallback.onScroll(l - oldl, t - oldt);
}
}
public OnScrollChangedCallback getOnScrollChangedCallback() {
return mOnScrollChangedCallback;
}
public void setOnScrollChangedCallback(
final OnScrollChangedCallback onScrollChangedCallback) {
mOnScrollChangedCallback = onScrollChangedCallback;
}
/**
* Impliment in the activity/fragment/view that you want to listen to the webview
* 這裏我們定義了一個OnScrollChangedCallback接口,其中dx和dy分別是滾動的時候,x和y方向上的
* 偏移量。這個偏移量是根據onScrollChanged方法的四個參數計算出來的:
*/
public static interface OnScrollChangedCallback {
public void onScroll(int dx, int dy);
}
}
mOnScrollChangedCallback.onScroll(l - oldl, t - oldt);
//現在一個對外提供了滾動參數的自定義webview:
wv = (ObservableWebView) findViewById(R.id.scorllableWebview);
wv.setOnScrollChangedCallback(new OnScrollChangedCallback(){
public void onScroll(int dx, int dy){
//這裏我們根據dx和dy參數做自己想做的事情
}
});
二:
Webview與js的雙向交互纔是android的webview強大所在
WebSettings webSettings = mWebView .getSettings();
webSettings.setJavaScriptEnabled(true);
mWebView.addJavascriptInterface(new Object() {
public void clickOnAndroid() {
// 加了一個post(new Runble),若不加的話js代碼是不被調用的。
mHandler.post(new Runnable() {
});
}
}, “demo”);
Android在4.4之前並沒有提供直接調用js函數並獲取值的方法,所以在此之前,常用的思路是 java調用js方法,js方法執行完畢,再次調用java代碼將值返回。
Android 4.4之後使用evaluateJavascript即可。
private void testEvaluateJavascript(WebView webView) {
webView.evaluateJavascript(“getGreetings()”, new ValueCallback() {
@Override
public void onReceiveValue(String value) {
Log.i(LOGTAG, “onReceiveValue value=” + value);
}
});
}
先寫這些吧,擼一把代碼吧。
附上一些了鏈接
HTML5,js與Android native通信
JS與移動端webview的相互交互
WebAPI