Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> JS和Android交互調用

JS和Android交互調用

編輯:關於Android編程

Android開發過程中,我們或多或少都會用到webview,使用webview來展示一些經常變動的界面更加方便簡單,也更易於維護。在使用webview來展示網頁的時候,有些時候我們需要通過JS和Android原生控件進行交互,以實現自己需要的效果或功能,本文通過一個demo簡單實現了JS和Android原生控件的交互。

界面上方是EditView和Button,下方是一個webview控件,通過輸入url,然後點擊跳轉按鈕,webview控件會加載該url,本次為了方便學習,我已經寫好了一個html文件放置在了Asset文件中,通過file:///android_asset/test.html來進行加載。然後出現四個新的按鈕,點擊不同的按鈕,會產生不同的效果。

asset文件夾下面的test.html文件
<meta charset="UTF-8" />
<meta content="EditPlus?" name="Generator" />
<meta content="" name="Author" />
<meta content="" name="Keywords" />
<meta content="" name="Description" />
<title></title>
<script>
    function jsAlert(){
        var r = alert("I am alert");
        alert(r);

    }
    function jsConFirm(){
        var r = confirm("I am conFirm");
        alert(r);

    }
    function jsPrompt(){
        //第一個參數是提示
        //第二個參數是默認值
        var r = prompt("請輸入姓名:","小明同學");
        alert(r);

    }
    function jsJava(){
        //調用java的方法,頂級對象,java方法
        //可以直接訪問JSTest,這是因為JSTest掛載到js的window對象下了
        JSTest.showToast("我是被JS執行的Android代碼");
    }
  </script>

代碼很簡單,整個界面只有四個按鈕,以及四個JS寫的方法jsAlert(),jsConFirm(),jsPrompt(),jsJava(),當點擊按鈕觸發這些方法的時候,會進一步觸發我們寫好的java代碼,具體實現請參見java代碼。

具體的java代碼
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.View;
import android.webkit.JavascriptInterface;
import android.webkit.JsPromptResult;
import android.webkit.JsResult;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.EditText;
import android.widget.Toast;

public class JSActivity extends AppCompatActivity {

    //assets下的文件的test.html所在的絕對路徑
    private static final String DEFAULT_URL = "file:///android_asset/test.html";

    private EditText et_url;

    private WebView webView;

    private ProgressDialog progressDialog;//加載界面的菊花

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_js);
        initView();
        initWebView();
    }

    /**
     * 初始化控件
     */
    private void initView() {
        webView = (WebView) findViewById(R.id.webView);
        et_url = (EditText) findViewById(R.id.et_url);
    }

    /**
     * 初始化webview
     */
    private void initWebView() {

        //首先設置Webview支持JS代碼
        webView.getSettings().setJavaScriptEnabled(true);

        //Webview自己處理超鏈接(Webview的監聽器非常多,封裝一個特殊的監聽類來處理)
        webView.setWebViewClient(new WebViewClient() {

            /**
             * 當打開超鏈接的時候,回調的方法
             * WebView:自己本身webView
             * url:即將打開的url
             */
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                //自己處理新的url
                webView.loadUrl(url);
                //true就是自己處理
                return true;
            }

            //重寫頁面打開和結束的監聽。添加友好,彈出菊花
            /**
             * 界面打開的回調
             */
            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                if (progressDialog != null && progressDialog.isShowing()) {
                    progressDialog.dismiss();
                }
                //彈出菊花
                progressDialog = new ProgressDialog(JSActivity.this);
                progressDialog.setTitle("提示");
                progressDialog.setMessage("軟軟正在拼命加載……");
                progressDialog.show();

            }

            /**
             * 界面打開完畢的回調
             */
            @Override
            public void onPageFinished(WebView view, String url) {
                //隱藏菊花:不為空,正在顯示。才隱藏
                if (progressDialog != null && progressDialog.isShowing()) {
                    progressDialog.dismiss();
                }

            }

        });

        //設置進度條
        //WebChromeClient與webViewClient的區別
        //webViewClient處理偏界面的操作:打開新界面,界面打開,界面打開結束
        //WebChromeClient處理偏js的操作
        webView.setWebChromeClient(new WebChromeClient() {
            /**
             * 進度改變的回調
             * WebView:就是本身
             * newProgress:即將要顯示的進度
             */
            @Override
            public void onProgressChanged(WebView view, int newProgress) {
                if (progressDialog != null && progressDialog.isShowing())
                    progressDialog.setMessage("軟軟正在拼命加載……" + newProgress + "%");
            }
            /**
             * 重寫alert、confirm和prompt的回調
             */
            /**
             * Webview加載html中有alert()執行的時候,回調
             * url:當前Webview顯示的url
             * message:alert的參數值
             * JsResult:java將結果回傳到js中
             */
            @Override
            public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {
                AlertDialog.Builder builder = new AlertDialog.Builder(JSActivity.this);
                builder.setTitle("提示");
                builder.setMessage(message);//這個message就是alert傳遞過來的值
                builder.setPositiveButton("確定", new OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        //處理確定按鈕了,且通過jsresult傳遞,告訴js點擊的是確定按鈕
                        result.confirm();
                    }
                });
                builder.show();
                //自己處理
                return true;
            }

            @Override
            public boolean onJsConfirm(WebView view, String url, String message, final JsResult result) {
                AlertDialog.Builder builder = new AlertDialog.Builder(JSActivity.this);
                builder.setTitle("提示");
                builder.setMessage(message);//這個message就是alert傳遞過來的值
                builder.setPositiveButton("確定", new OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        //處理確定按鈕了,且通過jsresult傳遞,告訴js點擊的是確定按鈕
                        result.confirm();
                    }
                });
                builder.setNegativeButton("取消", new OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        //處理取消按鈕,且通過jsresult傳遞,告訴js點擊的是取消按鈕
                        result.cancel();

                    }
                });
                builder.show();
                //自己處理
                return true;
            }

            /**
             * defaultValue就是prompt的第二個參數值,輸入框的默認值
             * JsPromptResult:向js回傳數據
             */
            @Override
            public boolean onJsPrompt(WebView view, String url, String message, String defaultValue,
                                      final JsPromptResult result) {
                AlertDialog.Builder builder = new AlertDialog.Builder(JSActivity.this);
                builder.setTitle("提示");
                builder.setMessage(message);//這個message就是alert傳遞過來的值
                //添加一個EditText
                final EditText editText = new EditText(JSActivity.this);
                editText.setText(defaultValue);//這個就是prompt 輸入框的默認值
                //添加到對話框
                builder.setView(editText);
                builder.setPositiveButton("確定", new OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        //獲取edittext的新輸入的值
                        String newValue = editText.getText().toString().trim();
                        //處理確定按鈕了,且過jsresult傳遞,告訴js點擊的是確定按鈕(參數就是輸入框新輸入的值,我們需要回傳到js中)
                        result.confirm(newValue);
                    }
                });
                builder.setNegativeButton("取消", new OnClickListener() {

                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        //處理取消按鈕,且過jsresult傳遞,告訴js點擊的是取消按鈕
                        result.cancel();

                    }
                });
                builder.show();
                //自己處理
                return true;
            }
        });

        //java與js回調,自定義方法
        //1.java調用js
        //2.js調用java
        //首先java暴露接口,供js調用
        /**
         * obj:暴露的要調用的對象
         * interfaceName:對象的映射名稱 ,object的對象名,在js中可以直接調用
         * 在html的js中:JSTest.showToast(msg)
         * 可以直接訪問JSTest,這是因為JSTest掛載到js的window對象下了
         */
        webView.addJavascriptInterface(new Object() {
            //定義要調用的方法,注意4.2及以後的則多了注釋語句@JavascriptInterface
            //msg由js調用的時候傳遞
            @JavascriptInterface
            public void showToast(String msg) {
                Toast.makeText(getApplicationContext(),
                        msg, Toast.LENGTH_SHORT).show();
            }
        }, "JSTest");

    }

    public void onClick(View view){
        String url = et_url.getText().toString().trim();
        if(TextUtils.isEmpty(url)){
            url = DEFAULT_URL;
        }
        webView.loadUrl(url);
    }


    @Override
    public void onBackPressed() {
        if (webView.canGoBack()) {
            //返回上一個頁
            webView.goBack();
            return ;
        }
        super.onBackPressed();
    }

}
布局文件activity_js.xml


    

        

代碼過程描述的廢話我就不多說了,注釋寫的算是比較仔細了,另外再強調兩點需要注意的地方:

一、不要忘記通過setJavaScriptEnabled(true)設置webview支持JS代碼

二、在使用addJavascriptInterface方法添加掛載對象時,要注意在Android4.2之後需要給對象方法加上@JavascriptInterface注解。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved