Android WebView初體驗

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章