web-dev-qa-db-fra.com

Android WebView JellyBean -> Ne devrait pas se produire: aucun noeud de test basé sur le rect n'a été trouvé

Mon application utilise beaucoup de vues Web qui se trouvent dans des fragments qui sont conservés par un ViewPager. 

Chaque fois que je glisse dans l'application sur mon Galaxy Nexus avec Jellybean, je reçois le message suivant de la console 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
Ostkontentitan

Le problème se produit car, dans certains scénarios, WebView ne remarque pas que son rect visible a été modifié. La page n'est donc toujours pas visible pour le kit de développement. Ainsi, toutes les touches tombent à l’extérieur de la fenêtre et sont rejetées.

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

Vous devrez sous-classer la vue Web pour promouvoir la méthode onScrollChanged protégée à une méthode publique.

21
John Reck

J'ai eu ce problème précis. Le problème est exactement ce que Rahul Dole a dit dans sa réponse ci-dessus. 

Je passe quelques jours à essayer des tonnes de choses différentes. J'ai remarqué que lorsque l'orientation changeait, la WebView visible OnLongClick fonctionnait à nouveau ... alors je suis venue avec ce petit bijou. En effet c'est très hacky mais ça marche!

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
Codeversed

J'ai exactement le même problème. Dans mon application, quel que soit l'endroit où j'avais des événements de clic codés à l'aide de 'touchend' dans jQuery bind (), cette erreur se produisait et elle ne répondait jamais aux clics (taps) .. juste essayé de remplacer 'touchend' par 'click' dans bind (), et cela a fonctionné! répondu aux clics (Taps) et n'a également pas montré cette entrée de journal de webcoreglue .. 

J'ai aussi trouvé ce morceau de code dans le code Webview d'Android.

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 cela aussi ..

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

Vous remarquez que le message du journal est là? Je suppose que ce code sert à identifier les vecteurs des axes x et y générés par des clics, des taps ou des balayages .. Le plus grand centre commercial

16
Rahul Dole

Je ne sais pas pourquoi cela a fonctionné. J'ai ajouté le programme d'écoute onTouchEvent dans mon MainActivity.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
Chadder43

Avoir le même problème avec les fragments JellyBean et ViewPager + qui contient WebViews. Et tout va bien avec le même code fonctionnant sur Android 2.2, donc je pense que c'est un bogue dans l'implémentation de JB WebView.

Sur JB, seul le premier fragment affiché avec WebView fonctionne correctement, sans erreur "dans le journal, cela ne devrait pas se produire", et les appels getHitTestResult () renvoient des valeurs correctes. En passant aux pages suivantes, j'ai eu des erreurs dans le journal et getHitTestResult () ne renvoie que des zéros et des valeurs NULL.

Maintenant, je n'ai trouvé qu'une solution pour créer des fragments avec des conteneurs vides et créer des WebViews, les configurer et charger des données uniquement lorsque le fragment actuel devient actif dans ViewPager. Dans ce cas, WebView fonctionne selon les besoins. Mais, malheureusement, cela casse complètement l’idée de glisser en douceur des pages dans ViewPager.

Ayez la dernière idée, demain tentera de remplacer les fragments de ViewPager par des vues composées. Peu de chances, mais je vous ferai savoir si les résultats seront fructueux.

1
Vlad Kuts

Une autre solution:

Vous n'avez pas besoin d'étendre la classe WebView pour résoudre ce problème. J'ai résolu le problème en ajoutant les deux lignes suivantes juste après le chargement du 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 cela a fonctionné).

À votre santé

0
Ahmed

Cela m'est également arrivé lorsque je travaillais dans l'environnement Cordova + Sencha Touch. Parce que CordovaActivity n'a rien de semblable à la méthode onScrollChanged(), je ne pouvais appliquer aucune des solutions ci-dessus. 

Après des heures passées à me cogner la tête contre le mur, j'ai découvert que certaines parties de l'interface Web avaient été appelées avant que cela soit complètement rendu. Dans mon cas, ces méthodes ont été déclenchées par l'événement activate dans Ext.PanelView. J'ai remplacé cet événement par painted et depuis lors, tout fonctionne à merveille.

Bien que ce ne soit pas une solution de copier-coller, j'espère que cela pourra aider quelqu'un à gagner du temps sur ses recherches.

0
Adam Bubela