Android WebView JellyBean – >不应该发生:找不到基于rect的testing节点
我的应用程序正在使用大量的Web浏览器,这些Web浏览器位于由ViewPager保存的片段中。
每当我滑过我的Galaxy Nexus上的应用程序与Jellybean上我一次又一次得到以下控制台消息:
08-23 13:44:03.374: E/webcoreglue(21690): Should not happen: no rect-based-test nodes found
任何人都可以向我解释什么是错的,以便我可以解决这个问题?
发生该问题是因为在某些情况下,WebView无法注意到其可见矩形已经更改,因此就webkit而言,该页面仍然不可见。 因此,所有的触摸都落在窗外,并被拒绝。
最清晰的修复方法是,当您知道WebView的可见性发生了变化(例如响应来自viewpager的setPrimaryItemcallback)时,请调用webview.onScrollChanged(webview.getScrollX(), webview.getScrollY());
您将需要inheritancewebview以将受保护的onScrollChanged提升为公共方法。
我有这个确切的问题。 问题正是Rahul Dole在他上面的回答中所说的。
我花了几天在这个尝试吨不同的东西。 我注意到,当方向改变时,可见的WebView onLongClick再次工作…所以我想出了这个小gem。 确实很黑,但它的作品!
在扩展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); }
我面对完全相同的问题。 在我的应用程序中,无论我点击使用jQuery的bind()中的'touchend'编码的事件,这个错误即将到来,它从来没有响应点击(水龙头)..给了一种冻结的感觉。 所以我只是尝试用bind()中的'click'来代替'touchend',它就起作用了! 响应点击(水龙头),也没有显示webcoreglue日志条目..
我也在Android的webview代码中find这段代码
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=%px=%dy=%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); }
这也是
// 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...
注意那里的日志消息? 我猜这个代码是用来识别点击或点击或刷卡生成的x和y轴向量..
与包含WebViews的JellyBean和ViewPager +片段有相同的问题。 和所有运行在Android 2.2上的代码一样OK,所以我认为这是JB WebView实现中的一个bug。
在JB上,只有WebView中显示的第一个片段正常工作,在日志中没有错误“不应该发生……”,并且getHitTestResult()调用返回正确的值。 滑动到下一页,我得到日志中的错误,getHitTestResult()只返回零和空值。
现在我发现只有一个解决scheme来创build带有空容器的碎片并创buildWebView,只有当ViewPager中的当前碎片变为活动时,才能设置它们并加载数据。 在这种情况下,WebView根据需要工作。 但不幸的是,这完全打破了在ViewPager中顺畅地滑动页面的想法。
有最后的想法,明天将尝试将ViewPager的片段replace为复合视图。 很less有机会,但是如果结果会成功,我会告诉你。
没有一个线索,为什么它的工作。 我添加了onTouchEvent监听器到我的MainActivity.java来解决这个问题。
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); } }
当我在Cordova + Sencha Touch环境中工作时,也发生在我身上。 因为CordovaActivity
没有像onScrollChanged()
方法的东西, onScrollChanged()
我不能应用上面的任何解决scheme。
几个小时后,我的头靠在墙上,发现Web界面的某些部分在被完全呈现之前被调用。 在我的情况下,这些方法是由Ext.PanelView
的activate
事件触发的。 我用painted
取代了那个事件,从那以后,一切都像魅力一样。
虽然这不是复制粘贴解决scheme,但我希望它可以帮助某人节省调查时间。
另一个scheme
你不需要扩展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);
希望这将有助于(我testing了自己,它的工作)。
干杯
即使我有一个ViewPager中的WebView,并通过扩展webview类来覆盖onTouchEvent()
来解决这个问题。
这是我的代码:
@Override public boolean onTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { requestFocusFromTouch(); } return super.onTouchEvent(event); }
干杯!