Android WebView JellyBean - >不应该发生:没有找到基于rect的测试节点

时间:2012-08-23 11:50:09

标签: android webview android-webview android-4.2-jelly-bean

我的应用程序正在使用大量网页视图,这些网页视图位于由ViewPager保存的片段中。

每当我使用Jellybean在我的Galaxy Nexus上移动应用程序时,我会一次又一次地收到以下控制台消息:

08-23 13:44:03.374: E/webcoreglue(21690): Should not happen: no rect-based-test nodes found

任何人都可以向我解释这里出了什么问题,以便我可以解决这个问题吗?

8 个答案:

答案 0 :(得分:21)

出现此问题是因为在某些情况下,WebView未发现其可见的rect已更改,因此就webkit而言,页面仍然不可见。因此,所有触摸都落在窗外,并被拒绝。

最干净的解决方法是,当您知道WebView的可见性发生变化时(例如响应来自viewpager的setPrimaryItem回调),请调用webview.onScrollChanged(webview.getScrollX(), webview.getScrollY());

您需要将webview子类化,以将受保护的onScrollChanged提升为公共方法。

答案 1 :(得分:18)

我有这个问题。问题正是Rahul Dole在上面的回答中所说的。

我花了几天时间尝试了很多不同的事情。我注意到当方向改变时,可见的WebView onLongClick再次工作......所以我想出了这个小宝石。确实它非常hacky但它​​的确有效!

在扩展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);
}

答案 2 :(得分:16)

我遇到了完全相同的问题。在我的应用程序中,无论我在jquery bind()中使用'touchend'编码的点击事件,这个错误都会出现,它过去常常从不响应点击(点击)...并给出了一种冷冻的感觉。 所以我只是尝试用bind()中的'click'替换'touchend',它有效!响应点击(点击)并且也没有显示webcoreglue的日志条目..

我还在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);
}​

这也是..

// 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轴向量。     

答案 3 :(得分:1)

与包含WebViews的JellyBean和ViewPager +片段存在同样的问题。使用在Android 2.2上运行的相同代码一切正常,所以我认为这是JB WebView实现中的一个错误。

在JB上,只有第一个显示的WebView片段工作正常,没有错误&#34;不应该发生..&#34;在日志中,getHitTestResult()调用返回正确的值。刷到下一页,我在log中遇到错误,getHitTestResult()只返回零和空值。

现在我发现只有一个解决方案来创建带有空容器的片段并创建WebViews,只有当当前片段在ViewPager中变为活动状态时才设置它们并加载数据。在这种情况下,WebView可以根据需要运行。但不幸的是,这完全打破了在ViewPager中平滑滑动页面的想法。

有了最后的想法,明天会尝试将ViewPager的片段替换为复合视图。几乎没有机会,但我会告诉您结果是否会成功。

答案 4 :(得分:1)

不知道为什么会有效。我将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);
      }
    }

答案 5 :(得分:0)

当我在Cordova + Sencha Touch环境中工作时,也发生在我身上。因为 CordovaActivity没有类似onScrollChanged()方法的内容我无法应用上述任何解决方案。

在我的头撞到墙壁几个小时之后,我发现在完全呈现之前已经调用了网络界面的某些部分。就我而言,这些方法是由activate中的Ext.PanelView事件触发的。我用painted替换了那个事件,从那以后一切都像魅力一样。

虽然它不是复制粘贴解决方案,但我希望它可以帮助某人节省调查时间。

答案 6 :(得分:0)

另一种解决方案:

您不需要扩展WebView类来解决这个问题。我已经通过在加载Web视图内容后立即添加以下两行来解决这个问题(myWebView.loadUrl(&#34; ...&#34):

wv.loadUrl("your url here");

//Add the following two lines
myWebView.scrollTo(myWebView.getScrollX(), myWebView.getScrollY()+1);
myWebView.scrollTo(myWebView.getScrollX(), myWebView.getScrollY()-1);

希望这会有所帮助(我测试了自己并且有效)。

干杯

答案 7 :(得分:-1)

即使我在ViewPager中有WebView,也可以通过扩展webview类来覆盖onTouchEvent()来解决这个问题。

这是我的代码:

@Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {       
            requestFocusFromTouch();
        }
        return super.onTouchEvent(event);
    }

干杯!!!