47

I have an issue with the WebView (Android 3.0+), which the WebView always displays a white background before display my black background ("flashing"). Here is my simple test code:

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

    WebView webView = new WebView(this);
    webView.setBackgroundColor(Color.BLACK);
    setContentView(webView);
    loadWebView(webView);
    webView.loadDataWithBaseURL("localhost://", "<html><head>" +
            "<style>body {background-color: #000}img{max-width:100%}</style></head>" +
            "<body>" +
            "<img src=\"http://developer.android.com/images/practices/actionbar-phone-splitaction.png\" />" +
            "</body></html>", 
            "text/html", "UTF-8", null);
}

I have tried many solutions to get rid of this problem, but not lucky.

PS: The problem will not appear if the hardware acceleration is turned off. Have anybody have the same problem and solved it?

Thank you.

leppie
  • 115,091
  • 17
  • 196
  • 297
Tri Bui
  • 1,266
  • 1
  • 11
  • 10
  • i have the same issue, could you find a solution about this? – bahadir arslan Mar 30 '12 at 13:42
  • 2
    We still have no solution/workaround. It is reported here: http://code.google.com/p/android/issues/detail?id=26138 and here https://code.google.com/p/android/issues/detail?id=25722 – Tri Bui Apr 04 '12 at 09:19
  • i solved my problem, webView.setBackgroundColor(0); have you tried it? – bahadir arslan Apr 04 '12 at 13:37
  • I tried, but it doesn't work. – Tri Bui Apr 11 '12 at 03:54
  • Just ran across this today. For some reason disabling hardware acceleration for the Activities in question isn't enough. You need to disable it for the whole application. –  Apr 20 '12 at 01:53
  • 2
    FYI: This bug is fixed in Jelly Bean. – Tri Bui Aug 09 '12 at 01:52
  • I've found a hacky workaround see my post: http://stackoverflow.com/a/17485236/923097 – Ingemar Jul 05 '13 at 09:16
  • This sounds slightly similar to a problem I was having awhile back. You can check out my SO question/answer here: http://stackoverflow.com/questions/13500452/android-webview-renders-blank-white-view-doesnt-update-on-css-changes-or-html – Kyle Jul 08 '13 at 17:15
  • @Ingemar Your resolution is to disable hardware acceleration, which will have a negative impact on performance and power consumption. – Paul Lammertsma Oct 02 '13 at 09:21
  • @Kyle Your resolution is to continuously call `invalidate()`, which will have a have a disastrous impact on power consumption. – Paul Lammertsma Oct 02 '13 at 09:22
  • This issue is not unique to the emulator, and it's also not fixed in Jelly Bean (or it broke again subsequently). – Nate Feb 25 '15 at 05:24

7 Answers7

56

I found the most effective fix for this, first mentioned here, was to set a transparent background color after the layout has been inflated:

webView.setBackgroundColor(Color.argb(1, 0, 0, 0));

Yes, it's a total hack, but it's the only solution I've found to work well without disabling hardware acceleration.

Note that this does not work through setting the background in XML.

This has been resolved in Jellybean, although some users have reported seeing this in KitKat. Check that you have not disabled hardware acceleration, and if the problem indeed disappears, you will probably want to wrap that code in a conditional statement to only target older devices:

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
    webView.setBackgroundColor(Color.argb(1, 0, 0, 0));
}
Paul Lammertsma
  • 37,593
  • 16
  • 136
  • 187
  • 5
    I was calling webView.setBackgroundColor( Color.TRANSPARENT ); but that did not work. However, no more flicker when using Color.argb(1,0,0,0) – John Weidner May 01 '13 at 02:25
  • I tried this but did not work. It only reduced the white flash to greyish flash. – DanKodi May 09 '13 at 07:13
  • Works, but on Android 2.3 it fills all webview with solid black. So we need some extra branching logic to make it universal. – Display Name Nov 13 '13 at 19:37
  • 1
    @PaulLammertsma i see this problem in kitkat, so wrapping the code and checking for up to jellybean, is wrong... – Lena Bru Jun 25 '14 at 06:37
  • 3
    Hi there. this fix worked for me in 4.4.4 (Nexus 5). I was suffering this flickering problem in a web view as well in 4.4.4. – Sotti Jul 19 '14 at 23:52
  • 2
    I can confirm that it is still a problem on Lollypop with the standard WebView (I'm using the UniWebView plugin for Unity3D) but this does fix the problem. – Sean Dawson Dec 10 '14 at 02:19
  • Worked like charm in Lollipop,set also the container to black and you are set! – visionix visionix Jul 03 '16 at 09:30
  • 3
    7 years later I still have this same problem inside a WebView where using setLayerType(HARDWARE,...) with kotlin causes the white flash. unfortunately, none of the solutions in this thread have worked so far. – cyfrost Jun 28 '20 at 08:01
  • 1
    Still seeing this issue on API 25 and the solution here does not work to resolve it, unfortunately. – PGMacDesign Jul 31 '20 at 23:26
13

I have enabled the hardware acceleration for the application and have disabled it for the activity. Additionally I set the background to null, as mentioned above. It works for me now.

Another approach (untested): set the layer type to software rendering and set the background to Color.TRANSPARENT (or 0): webview.setLayerType(View.LAYER_TYPE_SOFTWARE, null);

Greetz Thorsten

David
  • 4,027
  • 10
  • 50
  • 102
user640688
  • 321
  • 3
  • 10
10

Had this problem on Android 4.4.4 and none of the other solutions here worked. I was messing around with onPageFinished() anyway, so might as well try somthing that should be bullet proof:

I put this in the onCreateView() of the fragment that hosts the WebView:

    webView = (WebView) v.findViewById(R.id.webView);
    webView.setVisibility(View.INVISIBLE);
    webView.setBackgroundColor(Color.argb(1, 0, 0, 0));         

    webView.setWebViewClient( new WebViewClient(){
        @Override
        public void onPageFinished(WebView view, String url) {
            view.setVisibility(View.VISIBLE);
            super.onPageFinished(view, url);
        }
    });

The idea is simply to hide the WebView until the first page has loaded. However, it still gave me a small flash of white until I also added the solution provided by Paul Lammertsma, webView.setBackgroundColor(Color.argb(1, 0, 0, 0));

Magnus
  • 17,157
  • 19
  • 104
  • 189
  • Thanks! I have one issue though: the webview contents are now invisible (obviously) until it has completely finished loading. If my content has a lot of images that take some time to load, the whole contents are invisible while all the images are loading. I want the content to show immediately, while the images are loading, as the webview will nicely show the rest of the contents and add in the images when finished. But that does not work with this approach because we're hiding it. Any idea to fix this? I tried turning it visible in onPageStarted instead but that brings back the white flash :( – Nick Thissen May 16 '15 at 18:20
  • 1
    Not sure how that can be done, since I was loading a local HTML file from the assets folder I didn't have that problem. Perhaps you could try some sort of redirection? (i.e. loading one page, which in turn redirects to another page) – Magnus May 17 '15 at 16:52
5

It is obviously awful "feature" of Android version >3. Even official app Google Reader contains this white flash. Solution is to disable HW acceleration for the activity, where you need to use fast drawing web view.

Jan Muller
  • 402
  • 5
  • 8
1

Just go like this:

WebView web=(WebView)findViewById(R.id.web);
web.setBackgroundColor(0xff000000);
PYK
  • 3,674
  • 29
  • 17
1

It's 2021 and I still struggled with this and would like to share my experience. None of the solutions that I found worked. I cannot turn off the hardware acceleration for webview because that would mean too much performance hit. After trying a bunch of solutions, I realized that it is not possible to change the webview visibility from View.INVISIBLE to View.VISIBLE without causing flickering/blinking/flashing. So, I left the webview to be visible. However, I set the translucency of the webview to tranparent in the layout file. While a url is being loaded, the webview is transparent. Once the page is loaded, I set the webview to be opaque to show the webview on screen. Since there is no change of webview visibility, there is no flickering/blinking/flashing issue.

The layout file:

    <WebView
        android:id="@+id/WebView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_centerHorizontal="true"
        android:alpha="0.0"
        android:background="@android:color/transparent"
    />

MainActivity.kt:

    mWebView.webViewClient = object : WebViewClient() {
        override fun onPageFinished(view: WebView?, url: String?) {
            super.onPageFinished(view, url)

            // code for other stuff

            // Change the webview translucency from transparent to opaque.
            // This is a workaround of the Android bug of webview blinking when hardware acceleration is turned on
            // Basically, we cannot change the webview visibility to show and hide the webview.
            // Doing so would cause flickering/blinking with hardware acceleration).
            // Instead, the webview is visible the entire time.
            // We set the webview to be transparent while loading a page and then change the webview
            // to opaque once the page is loaded to make the webview visible to the user.
            if (mWebView.alpha < 1.0F) {
                mWebView.alpha = 1.0F
            }

            // more code for other stuff
        }
    }
BlackJerry
  • 78
  • 4
0

Had the similar problem with web view. I've worked on Ice Cream Sandwich and putting minSdk = 13 in Android Manifest worked for me. Try experimenting with that. I guess there is some bug in SDK.

Veljko
  • 1,893
  • 6
  • 28
  • 58