1. 程式人生 > >Android中與JS進行互動

Android中與JS進行互動

背景

我們在開發Android應用的時候,很多的時候需要跟網頁打交道,網頁與原生Android之間的互動就涉及到Java與JS之間的相互方法

WebView的使用

我們在Android中如果希望展示一個網頁,基本上都會使用WebView這個元件,它的基本使用也很簡單,假如我們希望載入一下百度首頁,可以像下面這樣寫: 首先在layout檔案中進行宣告

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
android:layout_height="match_parent" >
<WebView android:id="@+id/web_view" android:layout_width="match_parent" android:layout_height="match_parent" /> </RelativeLayout>

然後在java檔案中進行使用

WebView webView = (WebView) findViewById(R.id.web_view);
webView.loadUrl
("http://www.baidu.com");

同時,WebView還允許我們對一些預設設定進行修改,例如,我們希望啟動對javascript的支援並且可以進行縮放,就需要做如下設定:

// 啟用javascript
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setUseWideViewPort(true);

//是否可以縮放
webView.getSettings().setSupportZoom(true);
webView.getSettings().setBuiltInZoomControls
(true); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { getSettings().setDisplayZoomControls(false); }

但是,如果我們想要在頁面載入的時候處理各種通知、請求事件,或者監聽頁面的載入進度等,就需要用到另外兩個類:WebViewClient 和 WebChromeClient。其中,WebViewClient 主要用來監聽通知或請求事件,我們在開發中可能會用到的方法主要是下面幾個:

onPageStarted
onPageFinished
onReceivedError
shouldOverrideUrlLoading
public class CustomWebClient extends WebChromeClient { 
    @Override public void onProgressChanged(WebView view, int newProgress) { 
        if (newProgress == 100) { 
            mProgressBar.setVisibility(GONE); 
        } else { 
            if (mProgressBar.getVisibility() == GONE) { 
                mProgressBar.setVisibility(VISIBLE); 
            } 
            mProgressBar.setProgress(newProgress);
        } 
        super.onProgressChanged(view, newProgress); 
    }
}

除此之外,WebView還提供了直接執行javascript的功能,例如,我們可以簡單的彈出一個對話方塊:

webView.loadUrl("javascript:alert(\"提示資訊!\");");

當然,如果我們想要執行js,那麼必須滿足兩個條件,第一個是在設定中開啟javascript支援,即需要呼叫setJavascriptEnabled(true),第二個是需要設定WebChromeClient,兩者缺一不可。

程式碼演示

1.首先來一段最最簡單的jsp程式碼
 <body>
    <p>WebView與Javascript互動</p>
    <div>
        <button onClick="window.android.actionFromJs()">點選呼叫Android程式碼</button>
    </div>
    <br />
    <div>
        <button onClick="window.android.actionFromJsWithParam(' data come from Js')">點選呼叫Android程式碼並傳遞引數</button>
    </div>
    <br />
    <div id="log_msg">呼叫列印資訊</div>
    </body>
不傳遞引數:
    <button onClick="window.android.actionFromJs()">點選呼叫Android程式碼</button>

    將引數傳遞到android程式碼中
    <button onClick="window.android.actionFromJsWithParam('data come from Js')">點選呼叫Android程式碼並傳遞引數</button>
 // 啟用javascript
        mWebView.getSettings().setJavaScriptEnabled(true);
     /** 為webview添加註冊js 介面回撥監聽.
         *
         * 引數一: 介面物件
         * 引數二: 介面別名(別名讓js程式碼使用)
         * 如果別名寫"haha". 那麼js中就要寫window.haha.方法名
         */

        mWebView.addJavascriptInterface(this, "android");
/**
     * js呼叫此方法
     */
    @android.webkit.JavascriptInterface
    public void actionFromJs() {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(MainActivity.this, "js呼叫了Android函式", Toast.LENGTH_SHORT).show();
                String text = logTextView.getText() + "\njs呼叫了Android函式";
                logTextView.setText(text);
            }
        });
    }

    /**
     * js呼叫此方法. 並且將引數傳遞過來
     *
     * @param str js  傳遞過來的引數
     */
    @android.webkit.JavascriptInterface
    public void actionFromJsWithParam(final String str) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(MainActivity.this, "js呼叫了Android函式傳遞引數:" + str, Toast.LENGTH_SHORT).show();
                String text = logTextView.getText() + "\njs呼叫了Android函式傳遞引數:" + str;
                logTextView.setText(text);
            }
        });

    }
<html>
    <head>
    <script type="text/javascript">
    // 無參方法
    function actionFromNative() {
        document.getElementById("log_msg").innerHTML += "<br\>Android呼叫了js函式";
    }
    //有參方法
    function actionFromNativeWithParam(arg) {
        document.getElementById("log_msg").innerHTML += ("<br\>Android呼叫了js函式並傳遞引數:" + arg);
    }
    </script>
    </head>

    <body>
    <div id="log_msg">呼叫列印資訊</div>
    </body>
    </html>
 /**
         *  呼叫js.
         *  WebView.loadUrl("javascript:js中定義的方法")
         */
        button.setOnClickListener(new Button.OnClickListener() {
            public void onClick(View v) {
                // 無引數呼叫  android端呼叫js 方法
                mWebView.loadUrl("javascript:actionFromNative()");
                // 傳遞引數呼叫
                mWebView.loadUrl("javascript:actionFromNativeWithParam(" + "'come from Native'" + ")");
            }
        });
/**
         *  重寫這個方法的話,載入頁面就不會彈出瀏覽器打開了
         */
        mWebView.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                view.loadUrl(url);
                return true;
            }

            /**
             *  頁面載入完成回撥
             * @param view
             * @param url
             */
            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
            }
        });