Android WebView JellyBean -> ne devrait pas se produire: aucun noeud de test basé sur rect trouvé

mon application utilise beaucoup de webviews qui sont situés dans des fragments qui sont tenus par un ViewPager.

chaque fois que je passe à travers L'application sur mon Nexus Galaxy avec Jellybean dessus, je reçois le message de la console suivante encore et encore:

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

quelqu'un peut-il m'expliquer ce qui ne va pas ici pour que je puisse résoudre le problème?

47
demandé sur Ostkontentitan 2012-08-23 15:50:09

8 réponses

le problème se produit parce que dans certains scénarios WebView ne remarque pas que son rect visible a changé, donc en ce qui concerne webkit la page n'est toujours pas visible. Ainsi toutes les touches tombent à l'extérieur de la fenêtre, et sont rejetées.

le correctif le plus propre est quand vous savez que la visibilité de votre WebView a changé( par exemple en réponse à un rappel de setPrimaryItem depuis un viewpager), appelez webview.onScrollChanged(webview.getScrollX(), webview.getScrollY());

vous aurez besoin de sous-classe le webview pour promouvoir le protégé onScrollChanged pour une méthode publique.

21
répondu John Reck 2013-05-28 12:19:32

j'avais exactement ce problème. Le problème est exactement ce que Rahul Dole a dit dans sa réponse ci-dessus.

je passe quelques jours à essayer des tas de choses différentes. J'ai remarqué que quand L'orientation a changé que le WebView visible surlongclick fonctionnait à nouveau...alors j'ai trouvé ce petit bijou. En effet son très hacky mais il fonctionne!

utilisez ceci dans votre classe qui étend 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);
}
18
répondu Codeversed 2013-03-01 08:15:03

j'ai fait face exactement au même problème. Dans mon application, où que j'aie cliqué sur des événements codés en utilisant 'touchend' dans jQuery bind(), cette erreur se produisait et elle ne répondait jamais aux clics (taps).. et a donné une gelée de sens. Donc j'ai juste essayé de remplacer 'touchend' par 'click' dans bind(), et ça a marché! a répondu à des clics (Taps) et n'a pas non plus montré que l'entrée de journal de webcoreglue..

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

et ce trop..

// 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...

Notez que le message de log? Je suppose que ce code est pour identifier les vecteurs des axes x et y générés sur des clics ou des tapes ou des swipes.. ​

16
répondu Rahul Dole 2012-09-10 09:37:34

Ont le même problème avec JellyBean et ViewPager + fragments qui contient des WebViews. Et tout est OK avec le même code sous Android 2.2, donc je pense que c'est un bug dans L'implémentation de JB WebView.

sur JB seul le premier fragment montré avec WebView fonctionne correctement, sans erreurs "ne devrait pas se produire .."dans le journal, et getHitTestResult() appelle renvoie des valeurs correctes. En glissant vers les pages suivantes, j'ai eu des erreurs dans log et getHitTestResult () renvoie seulement des zéros et NULL.

maintenant je n'ai trouvé Qu'une seule solution pour créer des fragments avec des conteneurs vides et créer des WebViews, les configurer et charger des données seulement lorsque le fragment courant devient actif dans le ViewPager. Dans ce cas, WebView fonctionne selon les besoins. Mais, malheureusement, cela brise complètement une idée de pages glissantes lisses dans le ViewPager.

avoir la dernière idée, demain va essayer de remplacer les fragments de ViewPager pour composer des vues. Peu de chances, mais je vous ferai savoir si les résultats seront succès.

1
répondu Vlad Kuts 2012-12-04 22:32:29

Je n'ai pas la moindre idée de pourquoi ça a marché. J'ai ajouté ontouchevent listener à mon activité principale.java pour résoudre ce problème.

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);
      }
    }
1
répondu Chadder43 2015-06-09 10:13:50

cela m'est aussi arrivé quand je travaillais dans L'environnement Cordova + Sencha Touch. Parce CordovaActivity ne pas avoir quelque chose comme onScrollChanged() méthode je n'ai pu appliquer aucune des solutions ci-dessus.

après des heures de frapper ma tête contre le mur, j'ai découvert que certaines parties de l'interface web avaient été appelées avant que cela ne soit complètement Rendu. Dans mon cas, ces méthodes ont été déclenchés par activate événement Ext.PanelView. J'ai remplacé cet événement avec painted et depuis lors, tout fonctionne comme un charme.

bien qu'il ne s'agisse pas d'une solution de copier-coller, j'espère qu'elle pourra aider quelqu'un à gagner du temps sur l'enquête.

0
répondu Adam Bubela 2014-06-03 00:20:21

une autre solution:

Vous n'avez pas besoin d'étendre la classe WebView pour corriger cela.. J'ai corrigé cela en ajoutant les deux lignes suivantes juste après avoir chargé le contenu de la vue 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);

J'espère que cela va aider (je me suis testé et ça a marché).

Cheers

0
répondu Ahmed 2015-06-13 15:56:52

même J'ai WebView à l'intérieur d'un ViewPager, et j'ai corrigé ce problème en remplaçant onTouchEvent() en prolongeant la classe webview.

Voici mon code:

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

Cheers !!!

-1
répondu Audumbar 2016-06-07 15:42:52