当前位置: 首页 > 面试题库 >

了解Android的webview addjavascriptinterface

邬弘化
2023-03-14
问题内容

我知道要从Javascript到Java进行交互,您必须使用webview中的addjavascriptInterface方法注入Java对象。

这是我面临的问题。

  1. 我使用addJavascriptInterfaceJS中可用的方法注册了一个Java对象

  2. 我使用在网络视图中注入了一些JS webview.loadURL("javascript:XXX");

  3. 注入JS完成后,我将发送JS事件。

问题是,如果在执行步骤1之后立即执行以下Javascript:

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

我在控制台日志中收到“找不到myobject”。

我想知道是否有一段时间可以访问对象,如果可以,我如何知道应该等待多少时间来调用对象?


问题答案:

我想知道是否有一段时间我可以访问我的对象

是的,我认为有一个延迟,因为WebView.addJavascriptInterface它将在WebView的内部工作线程中运行。也许您已经考虑了这一点,并意识到WebView必须维护至少一个工作线程才能执行异步网络IO。也许您在使用WebView时也注意到了DDMS中的这些线程。

事实证明,它还使用线程为许多其他公共方法工作。我真的希望Google的文档能使这一点变得更加清晰!但我希望我能帮助您,并向您展示如何尝试自己确认这一点。

跟着我看一下WebView的源代码。它是相当可读的,即使您不能完全了解正在发生的事情,也可以通过回答有关线程的一些问题来进行跟踪。

您可以通过SDK管理器工具下载Android框架源代码,但它也已镜像到Github上,因此这就是我在此处链接的内容。我猜到了并选择了一个与ICS某些版本接近的标签。不难发现WebView.addJavascriptInterface。我只是用Google搜索“
WebView.java站点:github.com/android”。

该方法WebView.addJavascriptInterface向以下实例发送消息WebViewCore

mWebViewCore.sendMessage(EventHub.ADD_JS_INTERFACE, arg);

WebViewCore.java其中有许多称为的重载方法sendMessage,但是我们实际上不需要知道确切地调用了哪个方法,因为它们几乎是同一件事。甚至还有一条很好的评论可以给我们提示我们来对地方了!所有这些都委托给某个实例作为EventHub内部类。事实证明,此方法是同步的,并且正在将消息发送到的实例Handler,这很好地表明该方法可能正在另一个线程中运行,但是出于完整性考虑,让我们来看看!

Handler被实例化EventHub.transferMessages是从所谓的WebViewCore.initialize。有几个在这里跳,但最终我发现,这是从所谓runWebCoreThread(子类Runnable),这是一个新的实例沿着Thread正确的位置。

多么冒险!因此,即使我真的不能确定所有这些活动部件的运行状况,我还是很有信心地说这种方法不是同步的,并且会向WebView的工作线程发送一条消息。我希望这是有道理的!

如果是这样,我怎么知道我应该等多少时间才能打电话给我的物体?

不幸的是,我不知道答案。我正在研究这个确切的问题,并且在谷歌搜索过程中在StackOverflow上发现了这个问题。我认为您有以下选择,其中一些比其他选择更好或更容易:

1)只需Thread.sleep100毫秒或介于两者之间addJavascriptInterfaceloadUrl("javascript:...")。布莱奇,我不喜欢这样,但这可能是最简单的。

2)另一种可能性是,您可以WebView.loadUrl使用专门测试接口是否已设置的JavaScript代码段进行调用,并捕获尚未设置的接口抛出的ReferenceError。但是,您可能已经猜到了,这种涉及将JavaScript接口添加到WebView!

3)WebView.setWebChromeClient改为调用,并捕获JavaScript
alert()console.log。根据我的实验,此方法
同步的,因此没有延迟。(我已经在源代码中确认了这一点,但我将为读者提供练习的详细信息。)您可能应该提出一些特殊的字符串以供调用alert并在其中进行检查onJsAlert,因此您不仅要抓住所有alert()s。

很抱歉这个答案的长度,希望对您有所帮助。祝好运!



 类似资料:
  • 我不得不将Looper添加到以下代码中: 注意,在runnable中有一个runnable。嵌套的runnable通过处理程序执行。最初我没有Looper,但Android抱怨我需要调用Looper。在执行另一个线程之前进行准备。 我读了Looper的书,但它看起来还是有点神秘。它看起来像某种内部消息传递管道。我不清楚为什么这是必要的,因为没有消息从我的外部可运行程序传到我的内部可运行程序。尽管这

  • 这是我第一次在这里寻求帮助,我的部门(政府)已经在市场上发布了一些应用程序(Google Play),直到昨天,当我在Nexus上获得Jelly Bean 4.2时,加密和描述一直运行得很好。加密工作正常,它实际上加密了要存储的信息。虽然当解密它时,我得到了一个异常,就像这样:填充块损坏。我已经检查了字符串,并且它与其他设备上的字符串一致(出于测试目的使用相同的密钥),这意味着它完全相同。问题是我

  • 我在我的应用程序中实现了GCM,如入门页面所述,并使用了GCM。jar和gcm服务器。jar帮助程序库更容易实现。 但我想我误解了GCM的某些内容;因为我无法实现我想要的。 我希望用另一个密钥信息注册设备,而不仅仅是注册ID。例如,这是一个天气应用程序,用户可能希望获得关于一个或多个城市的通知。为了实现这一点,服务器需要城市名称或邮政编码来从其他来源获取天气信息,并在发布的城市有任何变化时推送回注

  • 本文向大家介绍Android嵌套滚动NestedScroll的实现了解一下,包括了Android嵌套滚动NestedScroll的实现了解一下的使用技巧和注意事项,需要的朋友参考一下 其实嵌套滚动已经算一个比较常见的特效了,下面这个动图就是嵌套滚动的一个例子: 看到这个动效,大家可能都知道可以用CoordinatorLayout去实现.其实CoordinatorLayout是基于NestedScr

  • 问题内容: 我不太清楚该在哪里抛出该异常。 例如,我正在实现接口,并且不希望任何人调用该方法: Future#get(long,TimeUnit)。 所以,我可以扔吗? 事情是方法的规范并没有说明抛出异常。反过来,例外 抛出以指示不支持请求的操作。 类UnsupportedOperationException 我的意思是,如果您不希望调用它,通常会抛出它,否则可能会因为不是所有方法都已实现而被认为

  • 问题内容: 我试图了解Go中的并发性。特别是,我编写了以下线程不安全程序: 我认识到我应该使用渠道来防止与发生竞争,但这不是重点。程序打印,然后似乎永远循环(不再打印任何内容)。我希望它能打印出无限的数字列表,可能由于竞态条件而跳过某些数字并重复其他数字(或更糟的是,在更新数字时打印数字)。 我的问题是:为什么程序只打印一行? 只是要清楚一点:对于这个玩具示例,我不是故意使用渠道。 问题答案: 关