Android WebView JellyBean → Не должно быть: не найдены узлы проверки на основе прямой основы

В моем приложении используется много веб-просмотров, которые лежат в фрагментах, которые хранятся в ViewPager.

Всякий раз, когда я просматриваю приложение на своем Galaxy Nexus с Jellybean, я получаю следующее консольное сообщение снова и снова:

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

Может ли кто-нибудь объяснить мне, что здесь происходит, чтобы я мог решить проблему?

Ответ 1

Проблема возникает из-за того, что в некоторых сценариях WebView не замечает, что его видимый прямоугольник изменился, так как webkit обеспокоен, страница все еще не видна. Таким образом, все штрихи выходят за пределы окна и отклоняются.

Самое чистое решение - когда вы знаете, что видимость вашего WebView изменилась (например, в ответ на обратный вызов setPrimaryItem из viewpager), вызовите webview.onScrollChanged(webview.getScrollX(), webview.getScrollY());

Вам необходимо подклассифицировать веб-просмотр, чтобы продвинуть защищенный onScrollChanged на общедоступный метод.

Ответ 2

У меня была эта точная проблема. Проблема в том, что сказал Рахул Доул в своем ответе выше.

Я провожу несколько дней на этой тонкости разных вещей. Я заметил, что когда ориентация изменилась, что видимый WebView onLongClick снова работал... так что я придумал этот маленький камень. Действительно, это очень хаки, но это работает!

Используйте это в своем классе, который расширяет 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);
}

Ответ 3

Я столкнулся с такой же проблемой. В моем приложении везде, где я нажимал события, закодированные с использованием "touchhend" в jquery bind(), эта ошибка возникала, и она никогда не реагировала на клики (краны).. и давала замороженное чувство. Поэтому я просто попытался заменить "touchhend" на 'click' в bind(), и он сработает! откликается на клики (краны), а также не показывает, что запись в журнале webcoreglue..

Я также нашел этот фрагмент кода в коде веб-браузера 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);
}​

и это тоже..

// 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, сгенерированных на кликах или кранах или меток.   

Ответ 4

Имеют ту же проблему с фрагментами JellyBean и ViewPager +, которые содержат WebView. И все ОК с тем же кодом работает на Android 2.2, поэтому я думаю, что это ошибка в реализации JB WebView.

В JB только первый показанный фрагмент с WebView работает правильно, без ошибок "Не должно произойти.." в журнале, а вызовы getHitTestResult() возвращают правильные значения. Перейдя на следующие страницы, я получил ошибки в журнале, и getHitTestResult() возвращает только нули и нули.

Теперь я нашел только одно решение для создания фрагментов с пустыми контейнерами и создания WebViews, настройки и загрузки данных только тогда, когда текущий ток активен в ViewPager. В этом случае WebView работает по мере необходимости. Но, к сожалению, это полностью нарушает идею гладких страниц прокрутки в ViewPager.

У вас есть последняя идея, завтра попытаемся заменить фрагменты ViewPager на сложные представления. Мало шансов, но я сообщу, если результаты будут успешными.

Ответ 5

Не знаю, почему это сработало. Я добавил слушателя 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);
      }
    }

Ответ 6

Это также случилось со мной, когда я работал в среде Cordova + Sencha Touch. Потому как CordovaActivity не имеет ничего похожего на метод onScrollChanged(), я не мог применить ни одно из вышеуказанных решений.

После нескольких часов ударов головой о стену я обнаружил, что некоторые части веб-интерфейса были вызваны до того, как это было полностью отображено. В моем случае эти методы были вызваны событием activate в Ext.PanelView. Я заменил это событие на painted, и с тех пор все работает как шарм.

Хотя это не приложение copy-paste, я надеюсь, что это поможет кому-то сэкономить время на расследовании.

Ответ 7

Другое решение:

Вам не нужно расширять класс WebView, чтобы исправить это. У меня это исправлено, добавив следующие две строки сразу после загрузки содержимого веб-представления (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);

Надеюсь, это поможет (я проверил себя, и это сработало).

Приветствия

Ответ 8

Даже у меня есть WebView внутри ViewPager и исправлена ​​эта проблема, переопределяя onTouchEvent(), расширяя класс webview.

Вот мой код:

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

Приветствия!!!