关闭 x
IT技术网
    技 采 号
    ITJS.cn - 技术改变世界
    • 实用工具
    • 菜鸟教程
    IT采购网 中国存储网 科技号 CIO智库

    IT技术网

    IT采购网
    • 首页
    • 行业资讯
    • 系统运维
      • 操作系统
        • Windows
        • Linux
        • Mac OS
      • 数据库
        • MySQL
        • Oracle
        • SQL Server
      • 网站建设
    • 人工智能
    • 半导体芯片
    • 笔记本电脑
    • 智能手机
    • 智能汽车
    • 编程语言
    IT技术网 - ITJS.CN
    首页 » JavaScript »Android中Java和JavaScript交互

    Android中Java和JavaScript交互

    2014-12-12 00:00:00 出处:cnblogs
    分享

    Android提供了一个很强大的Webview控件用来处理Web网页,而在网页中,JavaScript又是一个很举足轻重的脚本。本文将介绍如何实现Java代码和Javascript代码的相互调用。

    如何实现

    实现Java和js交互十分便捷。通常只需要以下几步。

    WebView开启JavaScript脚本执行 WebView设置供JavaScript调用的交互接口。 客户端和网页端编写调用对方的代码。

    本例代码

    为了便于讲解,先贴出全部代码

    Java代码

    package com.example.javajsinteractiondemo;
    
    import android.annotation.SuppressLint;
    import android.app.Activity;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.Menu;
    import android.webkit.JavascriptInterface;
    import android.webkit.WebChromeClient;
    import android.webkit.WebSettings;
    import android.webkit.WebView;
    import android.webkit.WebViewClient;
    import android.widget.Toast;
    
    public class MainActivity extends Activity {
      private static final String LOGTAG = "MainActivity";
      @SuppressLint("JavascriptInterface")
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
          final WebView myWebView = (WebView) findViewById(R.id.myWebView);
          WebSettings settings = myWebView.getSettings();
          settings.setJavaScriptEnabled(true);
          myWebView.addJavascriptInterface(new JsInteration(), "control");
          myWebView.setWebChromeClient(new WebChromeClient() {});
          myWebView.setWebViewClient(new WebViewClient() {
    
              @Override
              public void onPageFinished(WebView view, String url) {
                  super.onPageFinished(view, url);
                  testMethod(myWebView);
              }
    
          });
          myWebView.loadUrl("file:///android_asset/js_java_interaction.html");
      }
    
      private void testMethod(WebView webView) {
          String call = "javascript:sayHello()";
    
          call = "javascript:alertMessage("" + "content" + "")";
    
          call = "javascript:toastMessage("" + "content" + "")";
    
          call = "javascript:sumToJava(1,2)";
          webView.loadUrl(call);
    
      }
    
      public class JsInteration {
    
          @JavascriptInterface
          public void toastMessage(String message) {
              Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show();
          }
    
          @JavascriptInterface
          public void onSumResult(int result) {
              Log.i(LOGTAG, "onSumResult result=" + result);
          }
      }
    
    }

    前端网页代码

    <html>
    <script type="text/javascript">
        function sayHello() {
            alert("Hello")
        }
    
        function alertMessage(message) {
            alert(message)
        }
    
        function toastMessage(message) {
            window.control.toastMessage(message)
        }
    
        function sumToJava(number1, number2){
           window.control.onSumResult(number1 + number2)
        }
    </script>
    Java-Javascript Interaction In Android
    </html>

    调用示例

    js调用Java

    调用格式为window.jsInterfaceName.methodName(parameterValues) 此例中我们使用的是control作为注入接口名称。

    function toastMessage(message) {
      window.control.toastMessage(message)
    }
    
    function sumToJava(number1, number2){
       window.control.onSumResult(number1 + number2)
    }

    Java调用JS

    webView调用js的基本格式为webView.loadUrl(“javascript:methodName(parameterValues)”)

    调用js无参无返回值函数

    String call = "javascript:sayHello()";
    webView.loadUrl(call);

    调用js有参无返回值函数

    注意对于字符串作为参数值需要进行转义双引号。

    String call = "javascript:alertMessage("" + "content" + "")";
    webView.loadUrl(call);

    调用js有参数有返回值的函数

    Android在4.4之前并没有提供直接调用js函数并获取值的方法,所以在此之前,常用的思路是 java调用js方法,js方法执行完毕,再次调用java代码将值返回。

    1.Java调用js代码

    String call = "javascript:sumToJava(1,2)";
    webView.loadUrl(call);

    2.js函数处理,并将结果通过调用java方法返回

    function sumToJava(number1, number2){
           window.control.onSumResult(number1 + number2)
    }

    3.Java在回调方法中获取js函数返回值

    @JavascriptInterface
    public void onSumResult(int result) {
      Log.i(LOGTAG, "onSumResult result=" + result);
    }

    4.4处理

    Android 4.4之后使用evaluateJavascript即可。这里展示一个简单的交互示例 具有返回值的js方法

    function getGreetings() {
          return 1;
    }

    java代码时用evaluateJavascript方法调用

    private void testEvaluateJavascript(WebView webView) {
      webView.evaluateJavascript("getGreetings()", new ValueCallback<String>() {
    
      @Override
      public void onReceiveValue(String value) {
          Log.i(LOGTAG, "onReceiveValue value=" + value);
      }});
    }

    输出结果

    I/MainActivity( 1432): onReceiveValue value=1

    注意

    上面限定了结果返回结果为String,对于简单的类型会尝试转换成字符串返回,对于复杂的数据类型,建议以字符串形式的json返回。 evaluateJavascript方法必须在UI线程(主线程)调用,因此onReceiveValue也执行在主线程。

    疑问解答

    Alert无法弹出

    你应该是没有设置WebChromeClient,按照以下代码设置

    myWebView.setWebChromeClient(new WebChromeClient() {});

    Uncaught ReferenceError: functionName is not defined

    问题出现原因,网页的js代码没有加载完成,就调用了js方法。解决方法是在网页加载完成之后调用js方法

    myWebView.setWebViewClient(new WebViewClient() {
    
      @Override
      public void onPageFinished(WebView view, String url) {
          super.onPageFinished(view, url);
          //在这里执行你想调用的js函数
      }
    
    });

    Uncaught TypeError: Object [object Object] has no method

    安全限制问题

    假如只在4.2版本以上的机器出问题,那么就是系统处于安全限制的问题了。Android文档这样说的

    Caution: If you’ve set your targetSdkVersion to 17 or higher, you must add the @JavascriptInterface annotation to any method that you want available your web page code (the method must also be public). If you do not provide the annotation, then the method will not accessible by your web page when running on Android 4.2 or higher.

    中文大意为

    警告:假如你的程序目标平台是17或者是更高,你必须要在暴露给网页可调用的方法(这个方法必须是公开的)加上@JavascriptInterface注释。假如你不这样做的话,在4.2以以后的平台上,网页无法访问到你的方法。

    两种解决方法
    将targetSdkVersion设置成17或更高,引入@JavascriptInterface注释 自己创建一个注释接口名字为@JavascriptInterface,然后将其引入。注意这个接口不能混淆。

    注,创建@JavascriptInterface代码

    public @interface JavascriptInterface {
    
    }

    代码混淆问题

    假如在没有混淆的版本运行正常,在混淆后的版本的代码运行错误,并提示Uncaught TypeError: Object [object Object] has no method,那就是你没有做混淆例外处理。 在混淆文件加入类似这样的代码

    -keep class com.example.javajsinteractiondemo$JsInteration {
        *;
    }

    All WebView methods must be called on the same thread

    过滤日志曾发现过这个问题。

    E/StrictMode( 1546): java.lang.Throwable: A WebView method was called on thread 'JavaBridge'. All WebView methods must be called on the same thread. (Expected Looper Looper (main, tid 1) {528712d4} called on Looper (JavaBridge, tid 121) {52b6678c}, FYI main Looper is Looper (main, tid 1) {528712d4})
    E/StrictMode( 1546):   at android.webkit.WebView.checkThread(WebView.java:2063)
    E/StrictMode( 1546):   at android.webkit.WebView.loadUrl(WebView.java:794)
    E/StrictMode( 1546):   at com.xxx.xxxx.xxxx.xxxx.xxxxxxx$JavaScriptInterface.onCanGoBackResult(xxxx.java:96)
    E/StrictMode( 1546):   at com.android.org.chromium.base.SystemMessageHandler.nativeDoRunLoopOnce(Native Method)
    E/StrictMode( 1546):   at com.android.org.chromium.base.SystemMessageHandler.handleMessage(SystemMessageHandler.java:27)
    E/StrictMode( 1546):   at android.os.Handler.dispatchMessage(Handler.java:102)
    E/StrictMode( 1546):   at android.os.Looper.loop(Looper.java:136)
    E/StrictMode( 1546):   at android.os.HandlerThread.run(HandlerThread.java:61)

    在js调用后的Java回调线程并不是主线程。如打印日志可验证

    ThreadInfo=Thread[WebViewCoreThread,5,main]

    解决上述的异常,将webview操作放在主线程中即可。

    webView.post(new Runnable() {
        @Override
        public void run() {
            webView.loadUrl(YOUR_URL).
        }
    });
    上一篇返回首页 下一篇

    声明: 此文观点不代表本站立场;转载务必保留本文链接;版权疑问请联系我们。

    别人在看

    Edge浏览器百度被劫持/篡改怎么办,地址后边跟着尾巴#tn=68018901_7_oem_dg

    Google Chrome 在 iPhone 上新增了 Safari 数据导入选项

    Windows 11专业版 KMS工具激活产品密钥的方法

    DEDECMS安全策略官方出品

    Microsoft Text Input Application 可以关闭吗?

    新版本QQ如何关闭自带的浏览器?

    C++编程语言中continue的用法和功能,附举例示范代码

    c++ map 的数据结构、基本操作以及其在实际应用中的使用。

    C语言如何避免内存泄漏、缓冲区溢出、空指针解引用等常见的安全问题

    C语言中的break语句详解

    IT头条

    马斯克2026最新采访总结:2040年,全球机器人数量将突破100亿台

    23:52

    专家解读|规范人工智能前沿业态健康发展的新探索:解读《人工智能拟人化互动服务管理暂行办法》

    00:54

    用至强 6高存力搞定MoE卸载!

    17:53

    美国将允许英伟达向中国“经批准的客户”出售H200 GPU

    02:08

    苹果与微信就15%手续费达成一致?腾讯未置可否

    22:00

    技术热点

    PHP 和 Node.js 的10项对比挑战

    Javascript闭包深入解析及实现方法

    windows 7、windows 8.1手动增加右键菜单功能技巧

    MYSQL出错代码大汇总

    windows 7假死机怎么办 windows 7系统假死机的原因以及解决方法

    Ubuntu(Linux)下配置IP地址的方法

      友情链接:
    • IT采购网
    • 科技号
    • 中国存储网
    • 存储网
    • 半导体联盟
    • 医疗软件网
    • 软件中国
    • ITbrand
    • 采购中国
    • CIO智库
    • 考研题库
    • 法务网
    • AI工具网
    • 电子芯片网
    • 安全库
    • 隐私保护
    • 版权申明
    • 联系我们
    IT技术网 版权所有 © 2020-2025,京ICP备14047533号-20,Power by OK设计网

    在上方输入关键词后,回车键 开始搜索。Esc键 取消该搜索窗口。