3
votes

I'm using HTML5 AppCache to create an Android web app which can function offline. HTML which sources additional images, stylesheets, javascript and iframes is loaded into a WebView with loadDataWithBaseURL(). Unfortunately, when the device is offline only the HTML sourced in iframes is loaded from AppCache.

At this point, I know:

  • This content does exist in the AppCache, since I dumped the content of the AppCache.db file with adb shell and found all the content in there.
  • It's probably not a domain problem, since I'm specifying the correct path in the baseUrl field of loadDataWithBaseURL(). Also, a workaround to this problem succeeds without domain errors, as discussed below.

Here's some demo code:

public class ExampleActivity extends Activity {

   ...

  // HTML to be inserted into the Webview with loadDataWithBaseURL()
  public static final String ALL_HTML = 
      "<!DOCTYPE HTML><html>" +
      "<head><script src='sourced_js.js' " +
         "onload='console.log(\"sourced_js.js onload\");'>" +
      "</script>" +
      "<link rel='stylesheet' href='style.css' />" +   // doesn't load offline
      "</head><body>" +
      "<iframe src='manifest.html'></iframe>" +        // loads
      "<img src='android.jpg' />" +                    // doesn't load
      "<img src='android.gif' />" +                    // doesn't load
      "</body></html>";

  public void onCreate(Bundle savedInstanceState) {

    ...

    WebView webView = new WebView(context);
    webView.clearCache(true);

    WebSettings settings = webView.getSettings();
    settings.setAppCacheEnabled(true);
    settings.setJavaScriptEnabled(true);

    webView.loadDataWithBaseURL("http://my.website.com/path/to/content/",
        ALL_HTML, "text/html", "utf-8", null);
  }
}

manifest.html is just responsible for referencing the manifest. It looks like:

<html manifest="manifest.appcache">
<head></head>
<body></body>
</html>

manifest.appcache looks like:

CACHE MANIFEST

# Explicitly cached resources
# manifest.html automatically cached
sourced_js.js
android.jpg
android.gif
style.css

NETWORK:
*

When online, all content loads. When offline, only the iframe with manifest.html loads. The images, stylesheet and javascript are not loaded.

Strangely enough, if I source the exact same static content (sourced_js.js, android.jpg, ...) in manifest.html, they all load from AppCache in the iframe properly when the device is offline! As if these other resources have to be sourced secondarily from a static page.

Any clue why this content won't be loaded from the AppCache?

1

1 Answers

1
votes

The appcache should not work if you don't set the correct MIME type response setting (text/cache-manifest) for *.appcache files in your web server, according to the specs.

The same behavior is expected in desktop browsers, mobile browsers and iOS UIWebView.