5

I'm making an application which has a Webview inline with other elements, nested in a ScrollView. I've noticed that in ICS, testing on a Galaxy Nexus device, the WebView appears to be disjointed from the rest of the displayed elements when the page is flung, resulting in the WebView appearing to be floating because of a couple of ms worth of lag on drawing. This doesn't happen in 2.x versions of Android (not tested on 3.x). Here's a video of the floating effect http://www.youtube.com/watch?v=avfBoWmooM4 (you can see clearly if you set to fullscreen at 1080p)

Can anyone suggest why this may happen, or a fix?

I've setup a test project, below, to demonstrate:

package com.martynhaigh.floating_web_view;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebView;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;

public class FloatingWebViewTestActivity extends FragmentActivity {
    public final int viewId = 0x12345678;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        FrameLayout frame = new FrameLayout(this);
        frame.setId(viewId);
        setContentView(frame, lp);

        FloatingWebViewICSFragment fragment = new FloatingWebViewICSFragment();
        getSupportFragmentManager().beginTransaction().add(viewId, fragment).commit();
    }

    public static class FloatingWebViewICSFragment extends Fragment {

        private final String htmlBody = "<html><body><p style=\"font-size:1.5em\">This is a test document. This is a test document. This is a test document. This is a test document. This is a test document. This is a test document. This is a test document. This is a test document. This is a test document. This is a test document. This is a test document. This is a test document. This is a test document. This is a test document. This is a test document. This is a test document. This is a test document. This is a test document. This is a test document. This is a test document. This is a test document. This is a test document. This is a test document. This is a test document. This is a test document. This is a test document. This is a test document. This is a test document. </body></html>";

        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

            TextView textView = new TextView(getActivity().getApplicationContext());
            textView.setText("Test Activity");

            WebView webView = new WebView(getActivity().getApplicationContext());
            webView.loadDataWithBaseURL("file:///android_asset/", htmlBody, "text/html", "UTF-8", "about:blank");
            webView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
            webView.setScrollContainer(false);

            TextView textView2 = new TextView(getActivity().getApplicationContext());
            textView2.setText("Test Activity");

            FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT);

            LinearLayout layout = new LinearLayout(getActivity().getApplicationContext());
            layout.setLayoutParams(lp);
            layout.setOrientation(LinearLayout.VERTICAL);

            layout.addView(textView);
            layout.addView(webView);
            layout.addView(textView2);

            ScrollView scrollView = new ScrollView(getActivity().getApplicationContext());
            scrollView.setLayoutParams(lp);
            scrollView.addView(layout);

            return scrollView;
        }

    }
}
4

1 回答 1

1

我不知道如何解决它,但我现在是原因。WebView 的内容由 android.webkit.WebViewCore 在其单独的工作线程中呈现。他们正在互相交流。当 WebView 需要重新渲染时,它会向 WebViewCore 发送“请渲染”消息,当 WVC 准备好时,会发回结果。关键是它们的渲染与其他 UI 元素的渲染不同步 - 因为它是在单独的非 UI 线程上完成的。

我猜他们想避免在所有渲染工作中阻塞 ui 线程。这是非常亲切的。但它会导致其他问题......比如你的。

于 2012-02-17T15:36:42.320 回答