WebView doesn't load my HTML the second time?
Asked Answered
R

4

11

I've created a small Activity which is capable of loading two different HTML strings in a webview. When I run the Activity it starts by loading the String from the page_1 variable. So far so good. The page shows as expected. I've added an onFling listener which should make the activity load the content of the page_2 variable. The problem is that even though the onFling is called and the loadUrl is called the webview isn't updated?

My activity looks like this:

import android.app.Activity;
import android.os.Bundle;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.webkit.WebView;

public class Test extends Activity {
private GestureDetector mGestureDetector;
private WebView mWebView;
private int mPageIndex;

private static final String page_1 = "<html><body>Hello page 1</body></html>";
private static final String page_2 = "<html><body>Hello page 2</body></html>";

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.test);
  mWebView = (WebView) findViewById(R.id.webview);
  mWebView.loadData(page_1, "text/html", "utf-8");
  setupGestureDetection();
  mPageIndex = 0;
}

private void setupGestureDetection() {
  mGestureDetector = new GestureDetector(new MyGestureDetector());
  mWebView.setOnTouchListener(new OnTouchListener() {
    public boolean onTouch(View v, MotionEvent event) {
      return mGestureDetector.onTouchEvent(event);
    }
  });
}

class MyGestureDetector extends GestureDetector.SimpleOnGestureListener {
  private static final int SWIPE_DISTANCE_THRESHOLD = 120;
  private static final int SWIPE_VELOCITY_THRESHOLD = 200;

  private boolean isHorizontalSwipe(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
    if (Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) {
      if (Math.abs(e1.getX() - e2.getX()) > SWIPE_DISTANCE_THRESHOLD) {
        return true;
      }
    }
    return false;
}

@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
  if (isHorizontalSwipe(e1, e2, velocityX, velocityY)) {
    if (e1.getX() > e2.getX()) {
      // Right to left
      if (++mPageIndex % 2 == 0) {
        mWebView.loadData(page_1, "text/html", "utf-8");
      } else {
        mWebView.loadData(page_2, "text/html", "utf-8");
      }
      return true;
    }
  }
  return false;
}
}
}

My layout looks like this:

<?xml version="1.0" encoding="utf-8"?>
<WebView xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/webview"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent" />

I hope someone can help me! :-)

Best regards

Stig Andersen

Rosewater answered 25/1, 2012 at 8:40 Comment(2)
You can get error output from the web console if you add a WebChromeClient. mWebView.setWebChromeClient(new WebChromeClient()); should do it.Jingoism
Also, how do you know the loadData calls are being made? Are you stepping through with the debugger? Printing Log messages?Jingoism
C
10

First, try to avoid WebView#loadData(String, String, String) like the plague - it's a buggy p.o.s. Use WebView#loadDataWithBaseURL(String, String, String, String, String) instead.

Further, this will fix your problem. Counter-intuitive I know, but hey, it's the Android way.

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        if (isHorizontalSwipe(e1, e2, velocityX, velocityY)) {
            if (e1.getX() > e2.getX()) {
                // Right to left
                if (++mPageIndex % 2 == 0) {
                    mWebView.loadDataWithBaseURL(null, page_1, null, "utf-8", null);
                } else {
                    mWebView.loadDataWithBaseURL(null, page_2, null, "utf-8", null);
                }
                // Seriously. You must return false for the loadDataWithBaseURL to work. Not kidding. So you could skip this return.
                return false;
            }
        }
        return false;
    }
Chantalchantalle answered 25/1, 2012 at 9:31 Comment(2)
Hi Jens, You're my hero! Thanks for helping my out! :-)Rosewater
@Jens: Hi,I have got the same problem as Sting Andersen and tried your solution.But still,problem is there for not loading of content 2nd time? can you tell me,what else can be the solution other than this?Supervision
U
4

These solutions didn't work for me. what eventually worked is clearing the cache and history before loading the data (loadData worked in this case):

webView.clearCache(true);
webView.clearHistory();
webView.loadData(html, "text/html", "UTF-8");

Hope this will help.

Upanishad answered 7/11, 2012 at 10:28 Comment(2)
webView.loadDataWithBaseURL(null, html, null, "utf-8", null);Contumacious
Clearing cache and history is needed on certain OS levels (e.g. 4.1.1, but not 4.4.2) whenever a web view is reloaded with either load method. Even for a brand new web view - the underlying implementation appears to hold onto "old" content and uses the same URL (null in my case) to key to old content that no longer exists and hey presto an empty display. Two days, this just saved me after two days of banging my head against a wall with different devices having different behavior. Now to subclass my own web view so as not to forget about this again.Rite
M
4

Those who are still having the issue i found a quick solution just use a handler for this

Handler handler = new Handler();
handler.postDelayed(new Runnable() {
    @Override
    public void run() {
        webView.loadDataWithBaseURL("", html, "text/html", "UTF-8", null);
    }
}, 10) ;
Maturity answered 11/5, 2017 at 13:46 Comment(1)
Thank you for this comment! It was driving me crazy :) Solution in Kotlin: val handler = Handler() handler.postDelayed(Runnable { myWebview.loadUrl("example.com") }, 10). All other solution failed (clearing cache, destory(),...), for me only your solution works! Similar problem here: #55399918Jun
I
0

You need to set WebChromeClient on the webview, to make it properly work. You can override onConsoleMessage and check for any error logs.

webView.setWebChromeClient(new WebChromeClient() {
        @Override
        public boolean onConsoleMessage(ConsoleMessage consoleMessage) {
            ConsoleLogger.d(TAG, consoleMessage.message() + " -- From line "
                    + consoleMessage.lineNumber() + " of "
                    + consoleMessage.sourceId());
            return super.onConsoleMessage(consoleMessage);
        }
    });
Interdictory answered 8/6 at 17:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.