pengwei1024 / JsBridge

A simpler, extendable bidirectional communication Frame between Android WebView and Javascript
https://github.com/pengwei1024/JsBridge/wiki
Apache License 2.0
643 stars 88 forks source link

频繁调用一个定义的方法,h5有时候会收不到回调 #28

Open lodaDuan opened 4 years ago

lodaDuan commented 4 years ago

或者回调时间很长,超过1分钟。

pengwei1024 commented 4 years ago

注入的js方法执行线程是主线程哈,所以如果方法有耗时操作记得在子线程里面。你可以先检查下是不是耗时的问题。另外的方式就是用 chrome://inspect/#devices 看看JS是不是报错了,比如方法找不到之类的

lodaDuan commented 4 years ago

h5那是在JsBridge对象可以用后调用的,app的里面给h5调用的方法也不是耗时的,就返回一个json对象数据。日志里面看到app层已经回调给h5了,可是h5那边收不到回调,概率随机,访问越频繁越容易出现

pengwei1024 commented 4 years ago

方便贴一下 端上jsbridge大概实现吗?

lodaDuan commented 4 years ago

h5项目是用vuejs写的,虽然是单页面应用,发现h5页面加载的时候会多次执行onPageFinished,也就会注入多次,会不会这个原因导致。每次h5页面路由跳转的时候延时调用JsBridge就会有回调。

pengwei1024 commented 4 years ago

没关系的,最后只有一个全局对象。如果是前端调用后,端上又重新 onPageFinished 注入JS那就会有问题,你说的超过1min 还能回调恐怕不是这个问题。很可能是被阻塞住了。

lodaDuan commented 4 years ago

但是那个方法我写了一个简单html,里面的button点击一次调用一次JsBridge,一直点击调用都会有回调

lodaDuan commented 4 years ago

我改了一下onPageFinished回调里面的jsBridge.injectJs(view);只注入一次,后面再有回调也不执行jsBridge.injectJs(view);,发现h5回调正常了.

pengwei1024 commented 4 years ago

应该是多次注入,导致原先的回调变量名被重置了有关系。你尽量保证一个页面只初始化一次吧。

lodaDuan commented 4 years ago

有没有其他办法解决多次注入问题,如果再次注入不用重新new对象

pengwei1024 commented 4 years ago

有没有其他办法解决多次注入问题,如果再次注入不用重新new对象

这个只能修改注入的js,如果内存中已经存在window.jsBridge对象,就不再注入

lodaDuan commented 4 years ago

window.onJsBridgeReady好像只有在页面加载完成的时候回调一次,加载完再调用就不回调了,如何还能回调的话,我怎么修改下面代码呢,ready()方法好像没看到定义 this.OnJsBridgeReady = function() { try { var ready = window.onJsBridgeReady; if (ready && typeof(ready) === 'function') { ready() } else { var readyEvent = document.createEvent('Events'); readyEvent.initEvent('onJsBridgeReady'); document.dispatchEvent(readyEvent); } } catch(e) { console.error(e) }; };

pengwei1024 commented 4 years ago

ready 就是上面的变量,它其实是一个方法所以可以直接用 ready(), 多次调用直接多次执行 window.onJsBridgeReady() 就好

lodaDuan commented 4 years ago

js不太熟悉,那我怎么修改代码呢,现在只有JsBridge初始化完成才回调,后面再调用不回调了

pengwei1024 commented 4 years ago

只需要回调一次哈,因为jsbridge 的注入是异步的,所以需要通知前端已经注入完成,通知一次就可以了,没必要多次

lodaDuan commented 4 years ago

iOS那边可以多次回调,部分h5项目有些是window.onJsBridgeReady()回调里面调用jsbridge方法的,没有回调导致运行不起来,也没法找人家改。我就想想怎么修改代码实现即使jsbridge对象已经有了,也可以回调

pengwei1024 commented 4 years ago

注入代码主动执行下 window.onJsBridgeReady() 就行

lodaDuan commented 4 years ago

不是在这段代码里面修改吗 this.OnJsBridgeReady = function() { try { var ready = window.onJsBridgeReady; if (ready && typeof(ready) === 'function') { ready() } else { var readyEvent = document.createEvent('Events'); readyEvent.initEvent('onJsBridgeReady'); document.dispatchEvent(readyEvent); } } catch(e) { console.error(e) }; };

pengwei1024 commented 4 years ago

不是,注入完成才会执行这里,多次注入才能多次回调。不明白你的使用场景

lodaDuan commented 4 years ago

h5项目是vuejs写的,单页面应用,只有一个html,页面路由切换,会执行webview的onPageFinished回调,导致多次注入js,后来我修改了注入的代码,如果JsBridge对象已经有了,就不创建新的对象了。现在发现有些h5的项目是在每个路由页面里面调用window.onJsBridgeReady(),在回调里面调用JsBridge方法。因为第一个路由页面里面已经初始化完成了JsBridge,切换页面后导致其他页面的window.onJsBridgeReady()没有回调了。

lodaDuan commented 4 years ago

现在没法让h5那边的人去调整了,项目已经结束了

pengwei1024 commented 4 years ago

再改改注入的js代码就好,在判断 已经有 JsBridge的地方,直接调用 onJsBridgeReady

lodaDuan commented 4 years ago

可以是可以,但是h5 定义了window.onJsBridgeReady()的地方都会收到回调了

pengwei1024 commented 4 years ago

定义了window.onJsBridgeReady()的地方都会收到回调了

所以你想要的效果是咋样呢?

lodaDuan commented 4 years ago

搞明白了,window.onJsBridgeReady不叫回调,我的理解是定义了一个全局的函数,在注入的js成功后调用这个函数,如果多个vue页面里面定义了这个函数,调用时是最后一个定义函数的地方。 还没怎么接触过js,这次学到了不少东西。 谢谢您的细心指导。