精华内容
下载资源
问答
  • android demo,android调用h5中的js方法js方法在input中写入值,android中的java方法调用该js方法
  • 最近项目中有一个安卓JS交互的功能,安卓调用Js方法,总是不走,我的最初方法是: 这样一直不走JS方法,找了好久,都一头雾水,心态快炸了,就去厕所冷静了十分钟,心静下来,想了想我调的是一个方法,如果是...

    每天进步一点点。。。

    最近项目中有一个安卓与JS交互的功能,安卓调用Js方法,总是不走,我的最初方法是:

    这样一直不走JS方法,找了好久,都一头雾水,心态快炸了,就去厕所冷静了十分钟,心静下来,想了想我调的是一个方法,如果是原生的方法,字符串我是要加引号的,是不是这里也一样呢,就这样,我死马当活马医,抱着试试的心态,改改试试,如下:

    在字符串参数前面和后面加了个单引号转义字符,奇迹出现了,终于走通了,真的是被自己蠢哭了,记录一下,希望大家不要和我一样,被蠢哭。

    备注:1.参数前面引号与左括号(之间放个空格,参数后面引号与右括号)之间放个空格,亲自试过没有空格,有些时候也调不通,有空格就一定可以调通,具体原因有待进一步探索。

              2.有些时候(比喻参数是整形),就不需要加转义字符,但最好空格还是加上。

    展开全文
  • Android调用js方法js调用本地方法,简单明了
  • Android中Java调用JavaScript方法报错:Android中Java代码:webView.loadUrl("javascript:show('" + json + "')")//上边这行代码看着没有,但是有些时候回报如下错误:W/WebView: java.lang.Throwable: A WebView ...

    Android中Java调用JavaScript方法报错:

    Android中Java代码:

    webView.loadUrl("javascript:show('" + json + "')")//

    上边这行代码看着没有,但是有些时候回报如下错误:

    W/WebView: 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) {24c92049} called on Looper (JavaBridge, tid 5570) {2fd70380}, FYI main Looper is Looper (main, tid 1) {24c92049})

    at android.webkit.WebView.checkThread(WebView.java:2309)

    at android.webkit.WebView.loadUrl(WebView.java:884)

    at cn.qjnu.androidandh5.JsCallJavaCallPhoneActivity$JSCallJavaCallPhoneTest.showcontacts(JsCallJavaCallPhoneActivity.java:55)

    at com.android.org.chromium.base.SystemMessageHandler.nativeDoRunLoopOnce(Native Method)

    at com.android.org.chromium.base.SystemMessageHandler.handleMessage(SystemMessageHandler.java:28)

    at android.os.Handler.dispatchMessage(Handler.java:111)

    at android.os.Looper.loop(Looper.java:179)

    at android.os.HandlerThread.run(HandlerThread.java:61)

    W/System.err: java.lang.RuntimeException: 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) {24c92049} called on Looper (JavaBridge, tid 5570) {2fd70380}, FYI main Looper is Looper (main, tid 1) {24c92049})

    W/System.err: at android.webkit.WebView.checkThread(WebView.java:2319)

    W/System.err: at android.webkit.WebView.loadUrl(WebView.java:884)

    W/System.err: at cn.qjnu.androidandh5.JsCallJavaCallPhoneActivity$JSCallJavaCallPhoneTest.showcontacts(JsCallJavaCallPhoneActivity.java:55)

    W/System.err: at com.android.org.chromium.base.SystemMessageHandler.nativeDoRunLoopOnce(Native Method)

    W/System.err: at com.android.org.chromium.base.SystemMessageHandler.handleMessage(SystemMessageHandler.java:28)

    W/System.err: at android.os.Handler.dispatchMessage(Handler.java:111)

    W/System.err: at android.os.Looper.loop(Looper.java:179)

    W/System.err: at android.os.HandlerThread.run(HandlerThread.java:61)

    W/System.err: Caused by: 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) {24c92049} called on Looper (JavaBridge, tid 5570) {2fd70380}, FYI main Looper is Looper (main, tid 1) {24c92049})

    W/System.err: at android.webkit.WebView.checkThread(WebView.java:2309)

    W/System.err: ... 7 more

    解决办法,把webView.loadUrl(String url)放在webView.post(Runnable action)中执行即可解决:

    webView.post( new Runnable(){

    @Override

    public void run(0){

    webView.ladUrl(String url);

    }

    });

    展开全文
  • AndroidJS调用安卓方法介绍

    千次阅读 2016-09-19 17:59:11
    AndroidJS调用安卓方法介绍标签(空格分隔): android jsAndroidJS调用安卓方法介绍 1创建提供给JS调用方法 2在JS调用方法 3将对象传递个JS代码 Demo 1,创建提供给JS调用方法 @android.webkit....

    Android:JS调用安卓方法介绍

    标签(空格分隔): android js


    1,创建提供给JS调用的方法

        @android.webkit.JavascriptInterface
        fun showToast(name: String) {
            Toast.makeText(this, name, Toast.LENGTH_SHORT).show()
        }

    给方法声明@android.webkit.JavascriptInterface后表明该方法允许JS代码调用

    2,在JS中调用方法

        <!DOCTYPE html>
        <html>
            <head>
                <meta http-equiv="Content_Type" content="text/html;charset=utf-8"/>
                <title>Js调用Android</title>
            </head>
            <body>
                <input type="button" value="打招呼" onclick="myObj.showToast('孙悟空');"/>
            </body>
        </html>

    这里调用了上面提供的showToast方法

    3,将对象传递个JS代码

            val settings = mmWebView.settings
            settings.javaScriptEnabled = true
            mmWebView.addJavascriptInterface(object, "myObj")

    第一句取出WebView的设置对象,第二句允许执行JS代码,第三句发送方法所在的对象,并将方法命名为myObj

    Demo

    class MiniBrowserActivity : AppCompatActivity() {
        val js = """
        <!DOCTYPE html>
        <html>
            <head>
                <meta http-equiv="Content_Type" content="text/html;charset=utf-8"/>
                <title>Js调用Android</title>
            </head>
            <body>
                <input type="button" value="打招呼" onclick="myObj.showToast('孙悟空');"/>
            </body>
        </html>
        """
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_mini_browser)
    
            val settings = mmWebView.settings
            settings.javaScriptEnabled = true
            mmWebView.addJavascriptInterface(this, "myObj")
            mmWebView.loadData(js, "text/html;charset=utf-8", "utf-8")
        }
    
        @android.webkit.JavascriptInterface
        fun showToast(name: String) {
            Toast.makeText(this, name, Toast.LENGTH_SHORT).show()
        }
    }

    最终效果截图

    展开全文
  • 项目中为了减少端上开发量,通常会使用一些跨平台的解决方案,而 web 就是最简单、兼容性最强的方案,但 web 又受制于浏览器,不能直接访问系统的一些属性,而且我们也需要 web 调用 native 的一些方法,所以我们...

    项目中为了减少端上开发量,通常会使用一些跨平台的解决方案,而 web 就是最简单、兼容性最强的方案,但 web 又受制于浏览器,不能直接访问系统的一些属性,而且我们也需要 web 调用 native 的一些方法,所以我们需要一套 web 和 native 双向交互的方案。

    目前,Android 要实现与 web 交互有以下几种常用方案:

    WebView addJavascriptInterface方法

    拦截自定义协议链接实现数据交换

    实现 prompt,console等原生方法来数据交互

    方案一是官方推荐实现方案,但是在 android 4.2以下存在严重安全漏洞,而且和 JS 交换的数据仅仅局限于基本类型(int,float,double,String 等),不支持直接 JS 函数调用和回调(需要通过注入 JS 支持), 案例:wendux/DSBridge-Android

    方案二是兼容 iOS 的方案, 一般情况下前端需要依赖 JS 文件 或者 端上注入 JS, 调用方法固定,方法参数一般为: 函数名, 传递参数和回调函数, 传输数据长度就是 url 长度限制, 不支持同步回调,案例:lzyzsd / JsBridge 和

    marcuswestin / WebViewJavascriptBridge

    方案三是通过实现 Android WebView 原生方法来交互数据, 执行效率高,不限传输数据, 支持同步和异步传输,但也有弊端, 占据了系统函数,意味着前端使用这个函数就没效果了。

    我们今天要介绍的库就是基于第三种方案的改进,基于 prompt 方法来实现 Android 与 Javascript 双向交互。

    开源地址:https://github.com/pengwei1024/JsBridge

    为什么说它功能强大呢?它可以实现你要想的任意 JS 方法,支持 JS 函数,对象,数组等所有基础类型的解析和回调。我们先来看个示例吧。

    a1655bdd7562820f644e8c07dc3c30aa.gif

    如果要实现一个分享功能要怎么做呢?

    public class ServiceModule extends JsModule {

    @Override

    public String getModuleName() {

    return "service";

    }

    @JSBridgeMethod

    public void share(String msg, final JBCallback success, final JBCallback failure) {

    Intent intent = new Intent(Intent.ACTION_SEND);

    intent.setType("text/plain");

    intent.putExtra(Intent.EXTRA_TEXT, msg);

    if (intent.resolveActivity(getContext().getPackageManager()) != null) {

    getContext().startActivity(Intent.createChooser(intent, "share"));

    success.apply("success");

    } else {

    failure.apply("failure");

    }

    }

    JS 怎么调用呢?

    JsBridge.service.share('分享内容',

    function(){

    console.log('分享成功')

    },

    function(){

    console.log('分享失败')

    }

    )

    不用传递函数名, 调用的方法名和原生定义的方法名一致,参数支持所有 JS 类型(对象,数组等), 支持多个回调函数,回调函数参数也可以支持 JS 的所有类型,一看就和其他妖艳xx 不一样

    75362caf68b46376441636105dbe115a.gif

    你说 JS 可能没有成功失败的回调?没关系,我们支持缺省参数,下面这样也可以哟,不过原生方法 share 收到的 JBCallback 参数就为空咯

    JsBridge.service.share('分享内容');

    数据还不够复杂?实际开发情况数据复杂多了。

    e38b5849f4e67044e69ce5a9a66db10a.gif 那你看下面这样还行吗?JS 数组里基本包含了所有的类型

    JsBridge.share.test(

    [ - 1111111111111111111, 1.235, 'hello world', true,

    function(args) {

    alert(args)

    },

    {

    a: 100101,

    b: function() {

    alert('执行复杂回调函数')

    }

    },

    [1, 2, 3, 4]]);

    原生怎么解析这种情况呢?so easy, 不就一个 JBArray嘛

    3799c378531fb36b8331518f55f4d22c.png

    @JSBridgeMethod

    public void test(JBArray array) {

    for (int i = 0; i < array.size(); i++) {

    String output = "" + array.get(i);

    if (array.get(i) != null) {

    output += "##" + array.get(i).getClass();

    }

    Log.d(JsBridge.TAG, output);

    }

    array.getCallback(4).apply("xxx");

    array.getMap(5).getCallback("b").apply();

    }

    轻松回调 JS 数组里面的 function。JS 对象也不怕,JBMap全部搞定。

    调用方法只能三个层级?我们项目不需要 module!!就想 JsBridge.test 直接调用。老铁当然没问题啦,只要继承JsStaticModule, 里面的方法分分钟变成静态,对象名直接调用。

    public class ServiceModule extends JsStaticModule {

    ...

    }

    我们项目要求多个层级呢?

    需求还真多,多个层级是需要多少层级呢?4级够了吗?不行再多点?那你自己按需求定制吧!!

    53a6f18263bd5a1a6e21f0e99b97234c.gif

    public class ServiceModule extends JsModule {

    @Override

    public String getModuleName() {

    return "a.b.c.d.e.f.g";

    }

    }

    现在调用路径如下,

    068606b52ecf42e8e04a72a3dc718ebb.png 我不敢保证 FE 看到这个方法会不会拿刀去找你

    JsBridge.a.b.c.d.e.f.g.xx(...);

    iOS 要实现类似功能怎么办?

    1d55918ecf6d12a5196ebe3a0af882b2.gif

    我们推荐使用 marcuswestin / WebViewJavascriptBridge,JsBridge 是可以兼容这个库的。怎么兼容呢?iOS 的 WebViewJavascriptBridge不主要就是一个方法嘛?

    bridge.registerHandler("getCurrentPageUrl", function(data,responseCallback) {

    responseCallback(document.location.toString())

    })

    一个静态方法实现足以

    bb46c8a84c5efcda65849894d63c1aa2.png 怎么都觉得配合 iOS 这么强大的库就算杀鸡用牛刀了!

    介绍完功能,接下来我们从源码层面来介绍下JsBridge实现原理!

    在分析之前,我们先来了解几个相关知识点

    关键一: WebView 怎么执行 JS

    在 API 19+, 可以用系统方法

    WebView.evaluateJavascript("alert(1)", null)

    兼容所有版本的方案:

    WebView.loadUrl("javascript:alert(1)")

    有一点需要明确,JS的执行是异步进行的

    怎么利用执行 JS 注入一个对象呢?比如我需要一个对象JsBridge, 它包含一个 print()方法, JS 的语法是这样:

    var JsBridge = {

    print:function(msg){

    console.log(msg);

    }

    }

    WebView 只需要执行这段 JS 就好了

    WebView.loadUrl("javascript:var JsBridge = {print:function(msg){console.log(msg);}")

    在 JS 中就可以直接用JsBridge.print(1)来调用这个方法了

    关键二: onJsPrompt的参数了解

    onJsPrompt 是 WebChromeClient 接口的一个回调方法,用来处理prompt方法的回调。

    @Override

    public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {

    return true;

    }

    我们再看下 prompt的使用, 下面的代码网页中是什么效果呢?

    prompt("输入你的名字", "张三");

    9aa3d3cd809ad9bb25e389c2f2021e31.png

    prompt 第一个参数是标题,对应onJsPrompt方法的 message, 第二个参数是需要输入的内容的默认值, 对应`onJsPrompt的defaultValue, 那JsPromptResult是用来干啥的呢?我们实现同步回调就完全靠它了,用来设置 prompt 方法的返回值,假如我们端上执行JsPromptResult.confirm("12"), 那么 prompt(xx) 的返回值就是12

    基本的知识点我们都了解了,怎么串联起来上面的两条来实现WebView 和 JS 的双向交互呢?首先我们需要给 JS 提供调用方法, 如最早的JsBridge.service.share(...), 大概你已经知道了要用注入 JS 的方式。

    WebView.loadUrl("javascript:alert(1)")

    这样,在 JS 就可以执行上面的方法,接下来的问题就是我们怎么把 JS 的数据传递给 Android 呢?prompt 要上场了!

    JsBridge

    这样的话,在onJsPrompt的回调里message 就取到了 title。你就要问了,success 和 error 怎么传递给 Android 呢?这两个类型是 function, Android 和 JS 的 变量并不能共享或者相互转换,所以是做不到把 JS 的变量传递到 Android 的!那怎么去解决这个问题呢?

    既然不能转换,我们能不能换种思路,在分享执行完成的时候,我们需要执行 success 或者 error 来告诉 JS 分享结果,我们可以执行这个方法来实现呀,和 注入 JS 是一个套路,但是问题是对我们来说 success 和 error 是一个匿名方法(和 Java 的匿名内部类对象相似),我们并不知道怎么去调用它,这个容易解决呀,把这个函数赋值给一个已知名称的函数,然后我们在 Android 端调用已知名称的函数不就都解决了?我们来看下实现方式!

    print()

    Android 端实现

    var JsBridge = {

    print:function(msg){

    console.log(msg);

    }

    }

    这样 JS 就可以收到 success 回调了。

    以上 Android 和 JS 的双向交互原理都讲明白了,我们来看下JsBridge这个库是怎么实现的!就是两步走,注入 JS 和 接受和处理 JS 参数并回调。

    先看怎么注入的呢?

    JsBridge 需要继承JsModule来创建模块,然后模块里对方法添加JSBridgeMethod 注解的就是需要注入的方法。Java 方法的参数有一点的要求,和 JS 的参数有一个映射表

    Java 类型 | 映射的 JS 类型

    ----|------

    Boolean / boolean | Bool

    Integer/ int | Number

    Float / float | Number

    Double / double | Number

    Long / long | Number

    String | String

    JBCallback | function

    JBMap | Object

    JBArray | Array

    然后通过JsBridgeConfig.getSetting().registerDefaultModule(NativeModule.class) 或者 JsBridge.loadModule(NativeModule.class) 来注册 module。

    我们来看下注册的代码

    WebView.loadUrl("javascript:var JsBridge = {print:function(msg){console.log(msg);}")

    将 module.class 通过反射实例化对象,并获取这个类里面的所有有效注册方法存在 Map> 对象里面,注册就完成了,下面是注入 JS 的代码

    JsBridge.print(1)

    从Map>对象依次取出 Module, 并划分静态 module 和非静态, 原理就是把需要的 JS 对象和方法注入进去,这里复杂的问题是多级调用层级的实现,如前面提到的JsBridge.a.b.c.d.e.f.g.xx(...);, 这也是注册 module 时为什么要对 module 进行排序的原因,这里需要有一定 JS 面向对象基础才能看得明白些,就不细讲了,有兴趣的去分析下吧。

    再来就是获取 JS 的参数,并转化为 Java 的参数

    onJsPrompt

    JsBridge 是将参数包装成JBArgumentParser对象,获取 module 名称 和 method 名称, 从之前保存的 Map> 对象取出 JsMethod, JsMethod 里面包含了注解的 Java 反射的 Method 对象,通过反射调用 Method,并传递相应的参数 和 Context 对象,调用过程就完成了

    怎么回调呢?回调方法被包装成了 JBCallback 类,其实里面就是包含了一个 Webview 和 已知回调函数名称,在需要回调的地方调用 WebView 执行回调方法。里面设计到了对象的转换,把 Java 类型转换成JS 类型

    @Override

    public void apply(Object... args) {

    if (method == null || method.getModule() == null || method.getModule().mWebView == null

    || TextUtils.isEmpty(name)) {

    return;

    }

    String callback = method.getCallback();

    final StringBuilder builder = new StringBuilder("javascript:");

    builder.append("if(" + callback + " && " + callback + "['" + name + "']){");

    builder.append("var callback = " + callback + "['" + name + "'];");

    builder.append("if (typeof callback === 'function'){callback(");

    if (args != null && args.length > 0) {

    for (int i = 0; i < args.length; i++) {

    builder.append(JBUtils.toJsObject(args[i]));

    if (i != args.length - 1) {

    builder.append(",");

    }

    }

    }

    builder.append(")}else{console.error(callback + ' is not a function')}}");

    mHandler.post(new Runnable() {

    @Override

    public void run() {

    if (method.getModule().mWebView instanceof WebView) {

    ((WebView) method.getModule().mWebView).loadUrl(builder.toString());

    } else if (method.getModule().mWebView instanceof IWebView) {

    ((IWebView) method.getModule().mWebView).loadUrl(builder.toString());

    }

    }

    });

    }

    展开全文
  • JavascriptBridge 作者源地址: android app 演示 ①android 调用JS 方法,有参和无参 ②JS 调用 android 方法,有参和无参 的一个小例子
  • android 调用 js方法

    2019-10-31 11:30:46
    1、在调用js方法传参时,如果没放在onPageFinished回调中调用,没起效果,调用不到,为了防止以后再遇到这种坑,记录一下! contentWebView.getSettings().setJavaScriptEnabled(true); contentWebView....
  • JavaScript安卓交互之JS调用安卓方法,实现网页与安卓的交互。
  • js代码: &lt;!DOCTYPE html&gt; &lt;html&gt; &lt;head&gt; &lt;meta charset="utf-8"&gt; &... // JS代码 ...// Android需要调用方法 function
  • Androidjs的交互主要分为三种:1,安卓调用js方法。2,js调用安卓方法。3回调,即js调用安卓方法获得数据,然后数据回传给jsjs做业务处理。如有疑问可以看博客:...
  • Android调用JS方法没反应

    千次阅读 2020-01-20 11:15:05
    最近项目中有一个安卓JS交互的功能,安卓调用Js方法,总是不走,我的最初方法是: 这样一直不走JS方法,找了好久,都一头雾水,心态快炸了,就去厕所冷静了十分钟,心静下来,想了想我调的是一个方法,如果是...
  • 安卓调用JS方法 第一次调用有效果第二次调用打断点方法运行了但是就没有效果了 第一次评论调用JS方法成功了 然后你马上评论第一个就没有效果了!是什么意思 速求
  • android调用js js调用android webview调用js js调用webview
  • Android调用js方法调用失败。
  • 安卓Android源码——Android调用JavaScript.zip
  • Android 调用Js方法js回调Android方法

    千次阅读 2016-05-26 16:45:37
    Android native和webview中js交互主要是用android注解js方法。主要实现如下:直接上代码 js代码为: <!doctype html > <html><head> type= 'text/css' > html { font-family:Helvetica; color:#222...
  • 原生安卓js的交互WebView的基本使用基本配置原生安卓调用js原生安卓代码js代码 WebView的基本使用 基本配置 1.在xml里创建如下代码 <WebView android:id="@+id/web_view" android:layout_width="match_...
  • android传参html,调用js方法

    千次阅读 2018-08-20 16:26:11
    android 4.4前 webview.loadUrl(“javascript:test(\“传参成功\”)”); android 4.4后 webview.evaluateJavascript(js, new ValueCallback() { @Override ...
  • 主要介绍了android webview中使用Java调用JavaScript方法并获取返回值,本文直接出代码示例,需要的朋友可以参考下
  • ANDROID WEBVIEW和JAVASCRIPT交互_JS调用ANDROID方法
  • 主要介绍了AndroidJavaScript相互调用方法,实例分析了Android的WebView执行JavaScriptJavaScript访问Android的技巧,需要的朋友可以参考下
  • 分享大家供大家参考,具体如下:Android中可以使用WebView加载网页,同时Android端的Java代码可以与网页上的JavaScript代码之间相互调用。效果图:(一)Android部分:布局代码:xmlns:tools=...
  • 关于安卓调用js中的方法,参看我的文章android使用webView,实现和js中的方法调用js中调用安卓的原理其实很简单就是用了 “映射+调用” 首先前端的html界面有如下代码: <a onclick="dianwo()">点我</a&...
  • 那就是让Java代码和Javascript代码进行交互,然后在网上找到了关于webView的资料,之前并没有深入去了解WebView,一直以为Android 的WebView是一个用来显示网页的组件而已,没想到功能如此强大,竟然能跟JS互调传参,...
  • 第一步,android 中webview要设置支持 js settings.setJavaScriptEnabled(true); 第二步,要写一个专门处理这...client是标记 js调用android方法的一个标志, 然后,在处理类中,对应的方法要带上@Javascript
  • WebView 与 JavaScript 的交互 Android 调用 JS loadUrl() JS 中的方法需要在 window 对象下 Vue 中可以参考 ...function callJS() { alert("Android调用JS的callJS方法"); } mWebView.loadUrl("javas

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 108,701
精华内容 43,480
关键字:

给安卓调用的js方法