Android WebView JavaScript 交互

Android WebView 使用 JavaScript 可以完成 HTML5 与 Android 手机间的互相访问

  1. 定义一个类,用于将数据暴露出来,JS 通过该类公开的 (public) 添加了 @JavascriptInterface 注解的方法 访问 Android App 中的数据

    class JsObject {
        @JavascriptInterface
        public String toString() { return "injectedObject"; }
    }
    
  2. 设置 WebView 开启 JavaScript 支持

    webview.getSettings().setJavaScriptEnabled(true);  webview.addJavascriptInterface(object,"name");
    
  3. 在 JavaScript 或者 HTML 中调用 name.xxx 调用对象里的暴露的方法

    < input type="button" value="Toast提示" onclick="name.showToast('呵呵');"/>
    
  4. WebView 通过调用 evaluateJavascript() 方法调用 JavaScript 中的方法

    ms_webview.evaluateJavascript()(script, new ValueCallback<String>() {
        @Override
         public void onReceiveValue(String value) {
            // code here
        }
    });
    

HTML 通过 JS 显示 Toast 与普通列表的对话框


  1. 创建一个 空的 Android 项目 cn.twle.android.WebViewJavaScript

  2. 修改 AndroidManifest.xml 添加网络权限

    <uses-permission android:name="android.permission.INTERNET" />
    
  3. app 上点右键,然后选择 Folder - Assets Folder 创建 assets 目录,并在该名录下创建一个 HTML 文件 demo_e.html

    <!DOCTYPE html>
    <meta charset="utf-8" />
    <title>Android WebView JavaScript 交互</title>
    <h1>Android WebView JavaScript 交互</h1>
    <p><input type="button" value="弹出 Toast 提示" onclick="jsbridge.showToast('简单教程,简单编程');"/></p>
    <p><input type="button" value="弹出语言类表" onclick="jsbridge.showDialog();"/>
    <script>
        function show_dialog() {
            alert("简单教程的网址是:https://www.twle.cn/");
        }
    </script>
    

    或者直接使用我们的网址 https://www.twle.cn/static/i/android/demo_e.html

  4. 修改 activity_main.xml 添加一个 WebView

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:padding="5dp"
        android:layout_width="match_parent"    
        android:layout_height="match_parent">
        <WebView
            android:id="@+id/ms_webview"
            android:layout_width="match_parent" 
            android:layout_height="match_parent" />
    </RelativeLayout>
    
  5. 自定义一个 Object 对象 JsBridge.java,JavaScript 通过该类暴露的方法来调用 Android

    package cn.twle.android.webviewjavascript;
    
    import android.app.AlertDialog;
    import android.content.Context;
    import android.webkit.JavascriptInterface;
    import android.widget.Toast;
    
    public class JsBridge {
        private Context context;
    
        public JsBridge(Context context) {
            this.context = context;
        }
    
        //将显示 Toast 和对话框的方法暴露给 JavaScript 脚本调用
    
        @JavascriptInterface
        public void showToast(String name) {
            Toast.makeText(context, name, Toast.LENGTH_SHORT).show();
        }
    
        @JavascriptInterface
        public void showDialog() {
            new AlertDialog.Builder(context)
                    .setTitle("开发语言列表")
                    .setItems(new String[]{"Java", "C", "C++", "Python", "PHP"}, null)
                            .setPositiveButton("确定", null).create().show();
        }
    }
    
  6. 修改 MainActivity.java 启用 JavaScript 支持,然后通过 addJavascriptInterface() 暴露对象

    package cn.twle.android.webviewjavascript;
    
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.webkit.WebSettings;
    import android.webkit.WebView;
    
    public class MainActivity extends AppCompatActivity {
    
        private WebView ms_webview;
    
        //private static final String SITE_URL = "file:///android_asset/demo_e.html"
        private static final String SITE_URL = "https://www.twle.cn/static/i/android/demo_e.html";
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            ms_webview = (WebView) findViewById(R.id.ms_webview);
    
            WebSettings webSettings = ms_webview.getSettings();
            webSettings.setJavaScriptEnabled(true);
            webSettings.setDefaultTextEncodingName("UTF-8");
            // JsBridge 对象暴露给 JavaScript
            ms_webview.addJavascriptInterface(new JsBridge(MainActivity.this), "jsbridge");
    
            ms_webview.loadUrl(SITE_URL);
        }
    }
    

自定义 HTML 中的三种不同的对话框


  1. 创建一个 空的 Android 项目 cn.twle.android.WebViewCallJs

  2. 修改 AndroidManifest.xml 添加网络权限

    <uses-permission android:name="android.permission.INTERNET" />
    
  3. app 上点右键,然后选择 Folder - Assets Folder 创建 assets 目录,并在该名录下创建一个 HTML 文件 demo_f.html

    <!DOCTYPE html>
    <meta charset="utf-8" />
    <title>APP 通过 JavaScript 弹出 HTML 中的三种不同的对话框</title>
    <script>
        function alertFun()
        {
            alert("Alert 警告对话框!");
        }
        function confirmFun()
        {
            if(confirm("访问简单教程?"))
            {location.href = "https://www.twle.cn";}
            else alert("取消访问!");
        }
        function promptFun()
        {
            var word = prompt("Prompt 对话框","请输入点什么...:");
            if(word)
            {
                alert("你输入了:"+word)
            }else{
                alert("你什么都没写!");
            }
        }
    </script>
    <p>APP 通过 JavaScript 弹出 HTML 中的三种不同的对话框</p>
    <p>alert 对话框</p>
    <p>
        <input type="submit" name = "Submit1" value="展示1" onclick="alertFun()"/>
    </p>
    <p>Confirm对话框</p>
    <p>
        <input type="submit" name = "Submit2" value="展示2" onclick="confirmFun()"/>
    </p>
    <p>Prompt对话框</p>
    <p>
        <input type="submit" name = "Submit3" value="展示3" onclick="promptFun()"/>
    </p>
    

    或者直接使用我们的网址 https://www.twle.cn/static/i/android/demo_f.html

  4. 修改 activity_main.xml 添加一个 WebView

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:padding="5dp"
        android:layout_width="match_parent"    
        android:layout_height="match_parent">
        <WebView
            android:id="@+id/ms_webview"
            android:layout_width="match_parent" 
            android:layout_height="match_parent" />
    </RelativeLayout>
    
  5. 创建一个对话框布局 alertdialog.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
        <TextView
            android:id="@+id/text"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    
        <EditText
            android:id="@+id/edit"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:scrollHorizontally="true"
            android:selectAllOnFocus="true" />
    
    </LinearLayout>
    
  6. 修改 MainActivity.java

    package cn.twle.android.webviewjavascript;
    
    import android.content.Intent;
    import android.net.Uri;
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.webkit.WebSettings;
    import android.webkit.DownloadListener;
    import android.webkit.WebView;
    
    public class MainActivity extends AppCompatActivity {
    
        private WebView ms_webview;
    
        //private static final String SITE_URL = "file:///android_asset/demo_e.html"
        private static final String SITE_URL = "https://www.twle.cn/static/i/android/demo_f.html";
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            ms_webview = (WebView) findViewById(R.id.ms_webview);
    
            WebSettings webSettings = ms_webview.getSettings();
            webSettings.setJavaScriptEnabled(true);
            webSettings.setDefaultTextEncodingName("UTF-8");
            webSettings.setAllowFileAccess(true);
            webSettings.setBuiltInZoomControls(true);
    
            ms_webview.loadUrl(SITE_URL);
        }
    }
    
        //这里需要自定义一个类实现WebChromeClient类,并重写三种不同对话框的处理方法
        //分别重写onJsAlert,onJsConfirm,onJsPrompt方法
        class MyWebChromeClient extends WebChromeClient {
            @Override
            public boolean onJsAlert(WebView view, String url, String message,
                                     final JsResult result) {
                //创建一个Builder来显示网页中的对话框
                new Builder(MainActivity.this).setTitle("Alert对话框").setMessage(message)
                        .setPositiveButton("确定", new OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                result.confirm();
                            }
                        }).setCancelable(false).show();
                return true;
            }
    
            @Override
            public boolean onJsConfirm(WebView view, String url, String message,
                                       final JsResult result) {
                new Builder(MainActivity.this).setTitle("Confirm对话框").setMessage(message)
                        .setPositiveButton("确定", new OnClickListener() {
    
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                result.confirm();
                            }
                        })
                        .setNegativeButton("取消", new DialogInterface.OnClickListener() {
    
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                result.cancel();
                            }
                        }).setCancelable(false).show();
                return true;
            }
    
            @Override
            public boolean onJsPrompt(WebView view, String url, String message,
                                      String defaultValue, final JsPromptResult result) {
                //①获得一个LayoutInflater对象factory,加载指定布局成相应对象
                final LayoutInflater inflater = LayoutInflater.from(MainActivity.this);
                final View myview = inflater.inflate(R.layout.prompt_view, null);
                //设置TextView对应网页中的提示信息,edit设置来自于网页的默认文字
                ((TextView) myview.findViewById(R.id.text)).setText(message);
                ((EditText) myview.findViewById(R.id.edit)).setText(defaultValue);
                //定义对话框上的确定按钮
                new Builder(MainActivity.this).setTitle("Prompt对话框").setView(myview)
                        .setPositiveButton("确定", new OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                //单击确定后取得输入的值,传给网页处理
                                String value = ((EditText) myview.findViewById(R.id.edit)).getText().toString();
                                result.confirm(value);
                            }
                        })
                        .setNegativeButton("取消", new OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                result.cancel();
                            }
                        }).show();
                return true;
            }
    
        }
    }
    

Android 基础教程

关于   |   FAQ   |   我们的愿景   |   广告投放   |  博客

  简单教程,简单编程 - IT 入门首选站

Copyright © 2013-2022 简单教程 twle.cn All Rights Reserved.