了解Android的web视图addjavascriptinterface [英] Understanding Android's webview addjavascriptinterface

查看:105
本文介绍了了解Android的web视图addjavascriptinterface的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道,从JavaScript到Java交互,你必须使用addjavascriptInterface方法的WebView注入一个Java对象。

下面是我面临的问题。

  1. 我注册使用 addJavascriptInterface 方法是在我的JS提供的Java对象。

  2. 我注入使用web视图几个JS webview.loadURL(JavaScript的:XXX);

  3. 我送一个JS事件时,我与注射JS的我做了。

现在的问题是,如果第1步之后,如果我执行下面的JavaScript:

  mWebView.loadUrl(JavaScript的:如果(window.myobject)的console.log('MyObject来找到---------');其他{的console.log( 为MyObject没有找到----');});
 

我得到MyObject来未找到我的控制台的日志。

我想知道,如果有一段时间之前,我可以访问我的对象,如果是这样,我怎么知道我要多少时间等待叫我的对象?

解决方案
  

我想知道,如果有一段时间之前,我可以访问我的目标

是的,我认为是有延迟的,因为 WebView.addJavascriptInterface 将在web视图的内部工作线程运行。也许你已经想到这个问题,并意识到的WebView必须保持至少一个工作线程进行异步网络IO。也许你还同时使用的WebView注意到,在DDMS这些线程。

事实证明,它也使用一个线程做的工作为一定数量的其他公共方法。我真的希望从谷歌文档做出更清楚!但我希望我能帮助,告诉你我是如何设法证实这一点我自己。

请我,我看看源的WebView。这是相当可读的,即使你不能按照什么回事,有可能有些问题跟踪通过回答关于线程。

您也可以下载通过SDK管理器工具Android框架源代码,但它也反映在Github上,所以这就是我一直挂在这里。我猜,拿起一个标记,是接近一些版本的ICS。这不是很难找到<一href="https://github.com/android/platform_frameworks_base/blob/android-4.0.1_r1/core/java/android/webkit/WebView.java#L4022"><$c$c>WebView.addJavascriptInterface.我只是用Google搜索WebView.java网站:github.com/android。

方法 WebView.addJavascriptInterface 发送消息到实例 WebViewCore

  mWebViewCore.sendMessage(EventHub.ADD_JS_INTERFACE,ARG);
 

WebViewCore.java 还有一堆的重载方法称为<一个href="https://github.com/android/platform_frameworks_base/blob/android-4.0.1_r1/core/java/android/webkit/WebViewCore.java#L1734"><$c$c>sendMessage,但我们并不真正需要知道究竟是被称为,因为他们做的pretty的同样的事情。甚至还有一个很好的注释给我们一个提示,我们是在正确的地方!所有这些都委托给了一个实例<一href="https://github.com/android/platform_frameworks_base/blob/android-4.0.1_r1/core/java/android/webkit/WebViewCore.java#L920"><$c$c>EventHub这是一些内部类。 <一href="https://github.com/android/platform_frameworks_base/blob/android-4.0.1_r1/core/java/android/webkit/WebViewCore.java#L1652">This方法真可谓是同步的,并且将消息发送给处理程序,这是一个很好的迹象,这可能是在另一个线程中运行的实例,但为了完整起见,让我们来一探究竟吧!

这是处理程序中实例化的<一个href="https://github.com/android/platform_frameworks_base/blob/android-4.0.1_r1/core/java/android/webkit/WebViewCore.java#L1064"><$c$c>EventHub.transferMessages这是从<被叫href="https://github.com/android/platform_frameworks_base/blob/android-4.0.1_r1/core/java/android/webkit/WebViewCore.java#L209"><$c$c>WebViewCore.initialize.有几个跳在这里,但最终我发现,这是从运行 WebCoreThread 的(子类的Runnable ),这是伴随着一个新的发实例化右<一href="https://github.com/android/platform_frameworks_base/blob/android-4.0.1_r1/core/java/android/webkit/WebViewCore.java#L162">here.

这是多么的冒险!所以,即使我真的不能肯定地说什么与所有这些运动部件怎么回事,我是pretty的自信地说,这种方法是不同步的,并且将消息发送到web视图的工作线程。我希望这是有道理的!

  

如果是这样,我怎么知道我要多少时间等待叫我的对象?

不幸的是,我不知道这个问题的答案。我在研究这个确切的问题,并找到计算器这个问题在我的谷歌搜索的过程。我觉得你有以下几种选择,其中有些是比别人更好或更简单:

1)只要视频下载的之间的 addJavascriptInterface 使用loadURL 100毫秒或东西(JavaScript的:...)。布莱什,我不喜欢这一点,但它可能是最容易的。

2)另一种可能性是,你可以调用 WebView.loadUrl 使用JavaScript的代码段,专门测试,如果接口设置,并捕捉如果被抛出的ReferenceError它尚未设定。然而,正如你可能已经猜到了,这种涉及添加一个JavaScript接口的WebView!

3)呼叫 WebView.setWebChromeClient 代替,并赶上JavaScript的警报()的console.log 代替。从我的经验来说,这个方法的同步,所以没有延迟。 (我在源证实了这一点,但我会留下详细内容作为练习读者)你或许应该拿出一些特殊的字符串来调用警告与和检查它里面的 onJsAlert ,所以你不只是赶上所有的警报()秒。

对不起,这个答案的长度,我希望帮助。祝你好运!

I know that to interact from Javascript to Java you have to inject a Java object using the addjavascriptInterface method in webview.

Here is the problem I am facing.

  1. I register a java object using addJavascriptInterface method to be available in my JS.

  2. I inject few JS in the webview using webview.loadURL("javascript:XXX");

  3. I send a JS event when I am done with injecting the JS.

The problem is that if immediately after step 1, if I execute the following Javascript:

mWebView.loadUrl("javascript:if(window.myobject) console.log('myobject found---------'); else {console.log('myobject not found----');}");

I get "myobject not found" in my console's log.

I want to know that if there is some time before I can access my object and if so, how do I get to know how much time should I wait to call my object?

解决方案

I want to know that if there is some time before i can access my object

Yes, I think there is a delay, because WebView.addJavascriptInterface will run in the WebView's internal worker thread. Perhaps you've thought about this, and realized that WebView has to maintain at least one worker thread to do asynchronous network IO. Maybe you also noticed these threads in DDMS while using a WebView.

It turns out that it also uses a thread to do work for a number of other public methods. I really wish the docs from Google made this clearer! But I hope I can help and show you how I tried to confirm this for myself.

Follow me as I take a look at the source for WebView. It's reasonably readable, even if you can't follow exactly what's going on, it's possible to trace through answer some questions with respect to threads.

You can download the Android framework source through the SDK manager tool, but it's also mirrored on Github, so that's what I've linked to here. I guessed and picked a tag that's close to some version of ICS. It's not hard to find WebView.addJavascriptInterface. I just Googled "WebView.java site:github.com/android".

The method WebView.addJavascriptInterface sends a message to an instance of WebViewCore:

mWebViewCore.sendMessage(EventHub.ADD_JS_INTERFACE, arg);

In WebViewCore.java there are a bunch of overloaded methods called sendMessage, but we don't really need to know which exactly is being called, since they do pretty much the same thing. There's even a nice comment to give us a hint that we're in the right place! All of them are delegating to an instance of EventHub which is some inner class. This method turns out to be synchronized, and is sending a message to an instance of Handler, which is a good indication that this is probably running in another thread, but for completeness sake, let's find out!

That Handler is instantiated in EventHub.transferMessages which is called from WebViewCore.initialize. There are a few more hops here, but eventually I found out that this is called from run in WebCoreThread (subclass of Runnable), which is instantiated along with a new Thread right here.

What an adventure! So, even though I really can't say for sure what's going on with all these moving parts, I am pretty confident to say that this method is not synchronous, and sends a message to the WebView's worker thread. I hope that makes sense!

if so, how do i get to know how much time should i wait to call my object?

Unfortunately, I don't know the answer to this. I was researching this exact issue and found this question on StackOverflow in the course of my Googling. I think you have the following options, some of which are nicer or easier than others:

1) Just Thread.sleep for 100 ms or something between addJavascriptInterface and loadUrl("javascript:..."). Blech, I don't like this, but it is potentially the easiest.

2) Another possibility is that you could call WebView.loadUrl with a snippet of JavaScript that specifically tests if the interface is set, and catches the ReferenceError that is thrown if it's not set yet. However, as you might have guessed, this kind of involves adding a JavaScript interface to the WebView!

3) Call WebView.setWebChromeClient instead, and catch JavaScript's alert() or console.log instead. From my experiments, this method is synchronous, so there is no delay. (I have confirmed this in source, but I'll leave details as an exercise for the reader) You should probably come up with some special string to call alert with and check for it inside onJsAlert, so you aren't just catching all alert()s.

Sorry for the length of this answer, I hope that helps. Good luck!

这篇关于了解Android的web视图addjavascriptinterface的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆