Android WebView JellyBean -> 不应该发生:没有找到基于矩形的测试节点
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12090899/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Android WebView JellyBean -> Should not happen: no rect-based-test nodes found
提问by Ostkontentitan
My application is using a lot of webviews which are lying in fragments which are hold by a ViewPager.
我的应用程序使用了很多 webviews,它们位于由 ViewPager 保存的片段中。
Whenever i swipe through the app on my Galaxy Nexus with Jellybean on it i get the following console message again and again:
每当我在带有 Jellybean 的 Galaxy Nexus 上滑动应用程序时,我一次又一次地收到以下控制台消息:
08-23 13:44:03.374: E/webcoreglue(21690): Should not happen: no rect-based-test nodes found
Can anyone explain to me what is going wrong here so that i might be able to fix the issue?
谁能向我解释这里出了什么问题,以便我能够解决问题?
采纳答案by John Reck
The issue occurs because in some scenarios WebView fails to notice that its visible rect has changed, so as far as webkit is concerned the page is still not visible. Thus all touches fall outside of the window, and get rejected.
出现这个问题是因为在某些情况下,WebView 没有注意到它的可见 rect 发生了变化,因此就 webkit 而言,该页面仍然不可见。因此,所有接触都落在窗外,并被拒绝。
The cleanest fix is when you know the visibility of your WebView has changed (such as in response to a setPrimaryItem callback from a viewpager), call webview.onScrollChanged(webview.getScrollX(), webview.getScrollY());
最干净的修复是当您知道 WebView 的可见性已更改(例如响应来自 viewpager 的 setPrimaryItem 回调)时,调用 webview.onScrollChanged(webview.getScrollX(), webview.getScrollY());
You will need to subclass the webview to promote the protected onScrollChanged to a public method.
您需要将 webview 子类化以将受保护的 onScrollChanged 提升为公共方法。
回答by Codeversed
I had this exact issue. The problem is exactly what Rahul Dole said in his answer above.
我有这个确切的问题。问题正是 Rahul Dole 在上面的回答中所说的。
I spend a few days on this trying tons of different things. I noticed that when the orientation changed that the visible WebView onLongClick worked again...so I came up with this little gem. Indeed its very hacky but it works!
我花了几天的时间来尝试各种不同的东西。我注意到当方向改变时,可见的 WebView onLongClick 再次工作......所以我想出了这个小宝石。确实它非常hacky但它有效!
Use this in your class that extends WebView:
在扩展 WebView 的类中使用它:
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN){
int temp_ScrollY = getScrollY();
scrollTo(getScrollX(), getScrollY() + 1);
scrollTo(getScrollX(), temp_ScrollY);
}
return super.onTouchEvent(event);
}
回答by Rahul Dole
I faced exactly the same problem. In my app wherever i had click events coded using 'touchend' in jquery bind(), this error was coming up and it used to never respond to clicks (taps).. and gave a frozen kind of feel. So I just tried replacing 'touchend' with 'click' in bind(), and it worked! responded to clicks (Taps) and also didn't show that log entry of webcoreglue..
我遇到了完全相同的问题。在我的应用程序中,无论我在 jquery bind() 中使用“touchend”编码的点击事件,都会出现此错误,并且它过去永远不会响应点击(点击)......并给人一种冻结的感觉。所以我只是尝试在 bind() 中用 'click' 替换 'touchend',它奏效了!响应点击 (Taps) 并且也没有显示 webcoreglue 的日志条目..
I also found this piece of code in Android's webview code..
我也在Android的webview代码中找到了这段代码..
HTMLElement* WebViewCore::retrieveElement(int x, int y,
const QualifiedName& tagName)
{
HitTestResult hitTestResult = m_mainFrame->eventHandler()
->hitTestResultAtPoint(IntPoint(x, y), false, false,
DontHitTestScrollbars, HitTestRequest::Active | HitTestRequest::ReadOnly,
IntSize(1, 1));
if (!hitTestResult.innerNode() || !hitTestResult.innerNode()->inDocument()) {
LOGE("Should not happen: no in document Node found");
return 0;
}
const ListHashSet<RefPtr<Node> >& list = hitTestResult.rectBasedTestResult();
if (list.isEmpty()) {
LOGE("Should not happen: no rect-based-test nodes found");
return 0;
}
Node* node = hitTestResult.innerNode();
Node* element = node;
while (element && (!element->isElementNode()
|| !element->hasTagName(tagName))) {
element = element->parentNode();
}
DBG_NAV_LOGD("node=%p element=%p x=%d y=%d nodeName=%s tagName=%s", node,
element, x, y, node->nodeName().utf8().data(),
element ? ((Element*) element)->tagName().utf8().data() : "<none>");
return static_cast<WebCore::HTMLElement*>(element);
}?
and this too..
还有这个..
// get the highlight rectangles for the touch point (x, y) with the slop
Vector<IntRect> WebViewCore::getTouchHighlightRects(int x, int y, int slop)
{
Vector<IntRect> rects;
m_mousePos = IntPoint(x - m_scrollOffsetX, y - m_scrollOffsetY);
HitTestResult hitTestResult = m_mainFrame->eventHandler()->hitTestResultAtPoint(IntPoint(x, y),
false, false, DontHitTestScrollbars, HitTestRequest::Active | HitTestRequest::ReadOnly, IntSize(slop, slop));
if (!hitTestResult.innerNode() || !hitTestResult.innerNode()->inDocument()) {
LOGE("Should not happen: no in document Node found");
return rects;
}
const ListHashSet<RefPtr<Node> >& list = hitTestResult.rectBasedTestResult();
if (list.isEmpty()) {
LOGE("Should not happen: no rect-based-test nodes found");
return rects;
}
//Rest of the part is omitted here...
Notice that log message there? I am guessing this code is for identifying the x and y axis vectors generated on clicks or taps or swipes.. ?
注意到那里的日志消息了吗?我猜这个代码是为了识别在点击、点击或滑动时生成的 x 和 y 轴向量..?
回答by Vlad Kuts
Have the same problem with JellyBean and ViewPager + fragments that contains WebViews. And all OK with the same code running on Android 2.2, so I think this is a bug in JB WebView implementation.
JellyBean 和包含 WebView 的 ViewPager + 片段也有同样的问题。并且在 Android 2.2 上运行相同的代码都可以,所以我认为这是 JB WebView 实现中的一个错误。
On JB only the first shown fragment with WebView works right, without errors "Should not happen .." in the log, and getHitTestResult() calls returns correct values. Swiping to the next pages, I got errors in log and getHitTestResult() returns only zeroes and nulls.
在 JB 上,只有第一个显示的带有 WebView 的片段工作正常,日志中没有错误“不应该发生..”,并且 getHitTestResult() 调用返回正确的值。滑动到下一页,我在日志中遇到错误并且 getHitTestResult() 仅返回零和空值。
Now I found only one solution to create fragments with empty containers and create WebViews, setup they and load data only when current fragment becomes active in the ViewPager. In this case WebView works as needed. But, unfortunately, this completely breaks an idea of smooth swiping pages in the ViewPager.
现在我只找到了一种解决方案来创建带有空容器的片段并创建 WebView,设置它们并仅在当前片段在 ViewPager 中激活时加载数据。在这种情况下,WebView 根据需要工作。但是,不幸的是,这完全打破了 ViewPager 中平滑滑动页面的想法。
Have the last idea, tomorrow will try to replace ViewPager's fragments to compound views. Little chances, but I'll let you know if results will be successful.
有了最后的想法,明天试试把ViewPager的fragment替换成复合视图。机会很小,但我会告诉你结果是否会成功。
回答by Chadder43
Don't have a clue why it worked. I added onTouchEvent listener into my MainActivity.java to fix this issue.
不知道为什么它有效。我在 MainActivity.java 中添加了 onTouchEvent 监听器来解决这个问题。
public class MainActivity extends ActionBarActivity implements ActionBar.TabListener {
public class MyWebView extends WebView {
public MyWebView(Context context) {
super(context);
}
public MyWebView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
onScrollChanged(getScrollX(), getScrollY(), getScrollX(), getScrollY());
return super.onTouchEvent(event);
}
}
回答by Ahmed
Another solution:
另一种解决方案:
You don't need to extend the WebView class to fix that.. I've got that fixed by adding the following two lines right after loading the web view content (myWebView.loadUrl("..."):
你不需要扩展 WebView 类来解决这个问题。我通过在加载 web 视图内容后立即添加以下两行来解决这个问题 (myWebView.loadUrl("..."):
wv.loadUrl("your url here");
//Add the following two lines
myWebView.scrollTo(myWebView.getScrollX(), myWebView.getScrollY()+1);
myWebView.scrollTo(myWebView.getScrollX(), myWebView.getScrollY()-1);
Hope this will help (I tested myself and it worked).
希望这会有所帮助(我测试了自己并且有效)。
Cheers
干杯
回答by Adam Bubela
It also happened to me when I was working in Cordova + Sencha Touch environment. Because
CordovaActivity
does not have anything like onScrollChanged()
method I could not apply any of the above solutions.
当我在 Cordova + Sencha Touch 环境中工作时,这也发生在我身上。因为
CordovaActivity
没有任何类似的onScrollChanged()
方法,我无法应用上述任何解决方案。
After hours of banging my head against the wall I discovered that some parts of web interface had been called before this was completely rendered. In my case those methods were triggered by activate
event in Ext.PanelView
. I replaced that event with painted
and since then everything works like a charm.
在我的头撞墙数小时后,我发现在完全呈现之前已经调用了 Web 界面的某些部分。在我的情况下这些方法被触发activate
事件Ext.PanelView
。我替换了那个事件,painted
从那时起一切都像魅力一样。
Although it is not copy-paste solution I hope it may help someone to save time on investigation.
虽然它不是复制粘贴解决方案,但我希望它可以帮助某人节省调查时间。
回答by Audumbar
Even I have WebView inside a ViewPager, and fixed this problem by overriding onTouchEvent()
by extending webview class.
即使我在 ViewPager 中有 WebView,并onTouchEvent()
通过扩展 webview 类覆盖解决了这个问题。
Here is my code:
这是我的代码:
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
requestFocusFromTouch();
}
return super.onTouchEvent(event);
}
Cheers !!!
干杯!!!