HTML5 Cache, Android WebView

17 篇文章 0 订阅
7 篇文章 0 订阅

原文链接:http://alex.tapmania.org/2010/11/html5-cache-android-webview.html


HTML5 Cache, Android WebView

So last post was about HTML5 and WebViews but it didn’t cover offline usage and especially caching.
HTML5 is cool. It can work offline once cached by the browser. The main mechanism for offline HTML5 is the so called Manifest. Basically it’s a file which lists entries (js files, pictures, css, etc.) to be cached by the browser.

To enable cache in Android’s WebView we must do at least the following:

  1. webView. setWebChromeClient ( new WebChromeClient ( )  {
  2.       @Override
  3.        public  void onReachedMaxAppCacheSize ( long spaceNeeded,  long totalUsedQuota,
  4.                    WebStorage. QuotaUpdater quotaUpdater )
  5.        {
  6.             quotaUpdater. updateQuota (spaceNeeded  *  2 ) ;
  7.        }
  8. } ) ;
  9.  
  10. webView. getSettings ( ). setDomStorageEnabled ( true ) ;
  11.  
  12. // Set cache size to 8 mb by default. should be more than enough
  13. webView. getSettings ( ). setAppCacheMaxSize ( 1024 * 1024 * 8 ) ;
  14.  
  15. // This next one is crazy. It's the DEFAULT location for your app's cache
  16. // But it didn't work for me without this line.
  17. // UPDATE: no hardcoded path. Thanks to Kevin Hawkins
  18. String appCachePath = getApplicationContext ( ). getCacheDir ( ). getAbsolutePath ( ) ;
  19. webView. getSettings ( ). setAppCachePath (appCachePath ) ;
  20. webView. getSettings ( ). setAllowFileAccess ( true ) ;
  21. webView. getSettings ( ). setAppCacheEnabled ( true ) ;

This will work. Well, this will make your WebView support caching.. doesn’t mean it will actually work.
You can tune cache policies using the following code, even though it’s not required to make it work:

  1. webView. getSettings ( ). setCacheMode (WebSettings. LOAD_DEFAULT ) ;

Now when all the cache is setup we would like to see our HTML5 site working in pure offline mode.. but we don’t!
Why? well.. if it’s not working for you it probably means that the site you load up with the following call is actually redirecting you somewhere else:

  1. webView. loadUrl ( "http://myHTML5app.com/app/" ) ;

If /app/ is resolving to a redirect – you are in trouble, sir.
The Cache mechanism will cache the actual RESULT of the redirect and sure it will map it to the url you are being REDIRECTED to, not the one you originally called. So once you are offline – the cache has no clue about the /app/ url and thus you are simply given the default android “can’t open page” replacement.

There are at least two ways to solve this issue..

  • Get rid of the redirect on the server
  • Re-redirect on android side

    The first option is bad because you typically don’t want to mess with the working HTML5 site which is working on pure Browsers (iPhone, desktop, etc.).
    To implement the second option I used the following code in the WebViewClient implementation:

    1. @Override
    2. public  void onReceivedError (WebView view,  int errorCode,
    3.             String description,  String failingUrl )
    4. {
    5.      // The magic redirect  
    6.      if (  "http://HTML5app.com/app/". equals (failingUrl )  )  {
    7.            // main.html is the place we are redirected to by the server if we are online
    8.           mWebView. loadUrl ( "http://HTML5app.com/app/main.html" ) ;
    9.            return ;    
    10.      }
    11.      else  if (  "http://HTML5app.com/app/main.html". equals (failingUrl )  )  {    
    12.            // The cache failed – We don't have an offline version to show
    13.  
    14.            // This code removes the ugly android's "can't open page"
    15.            // and simply shows a dialog stating we have no network
    16.           view. loadData ( """text/html""UTF-8" ) ;
    17.           showDialog (DIALOG_NONETWORK ) ;
    18.      }
    19. }

    Good luck!

    Tags: 

19 Responses to “HTML5 Cache, Android WebView”

  1. Andrey Says: 

    Great blog it’s not often that I comment but I felt you deserve it.

  2. Tom Says: 

    Thanks a bunch, this helped me out =)

  3. Rishikesh Says: 

    Really awesome
    :D

  4. Leimi Says: 

    Hi,

    Great article ;) But even by following it, I can’t manage to enable the HTML 5 manifest in the WebView.
    The default Android browser notices the manifest file when I’m offline, but a WebView doesn’t and directly shows the “no internet connection” message.

    Do you have any idea why? Thanks :)

  5. Godexsoft Says: 

    Hi Leimi,

    Alas, I don’t remember doing anything special to get the manifest working.. I believe that it should just work if your html5 application works on the stock browser. The only difference might be your android being 2.2 or 2.3 against 2.1 used for this article.. maybe they changed something in newer versions of android.

    Hope you can find a solution soon. When you do – let me know :)
    Cheers,
    Alex

  6. Leimi Says: 

    Hmm, that’s weird, the code is done with the Android 2.1 SDK. Well, I’ll try harder and come back here if I find a solution :p

  7. Anand Says: 

    It’s a great blog Alex… Thnx

  8. Abp_Dk Says: 

    I faced this problem http://code.google.com/p/android/issues/detail?id=7939 on HTC Desire Api 2.2 since I used


    webView.getSettings().setAppCachePath("/data/data/com.your.package.appname/cache");

    as described in the article. Changing this to


    webView.getSettings().setAppCachePath("/data/data/[packagename]/cache");

    According to packagename in manifest

    This resolved the issue

  9. Novia Says: 

    Thanks..

    but in my side, eveything works well except when broswer get new version of cache, always fire ‘Error’ event of appCache and should be fire ‘UpdateReady’ event. I can’t find out the reason. Anybody Help me?

    I am really green in android developing field.

  10. Novia Says: 

    Any help is greatly appreciated. :)

  11. Derp Says: 

    Tack random crap!

  12. Astro Says: 

    Thanks!!!!!!

    very very helpful~!! :)

  13. Thorsten Says: 

    Instead to hardcode the cache dir it’s suggested to use getCacheDir() from the Context class (resp. getExternalCacheDir()).

  14. Kevin Hawkins Says: 

    This has been a tremendous help, so thank you!

    A couple of things. First, since I abhor literal paths coded into applications, I had to find another way to get the app cache path. ;-) I’d recommend this update:

    String appCachePath = getApplicationContext().getCacheDir().getAbsolutePath();
    webView.getSettings().setAppCachePath(appCachePath);

    Second, the WebChromeClient updates aren’t strictly necessary to make caching work. Of course, if you run into situations where your cache *does* get maxed out, making the WebChromeClient additions is a more robust way to handle that situation. But I was able to get by without it.

    Thanks again!

  15. Godexsoft Says: 

    Hi Kevin, I’m glad my post helped you out.
    Thanks for the update suggestion. I merged your code into the post :)

    Cheers,
    Alex

  16. Jordan Says: 

    showDialog(DIALOG_NONETWORK); has been depreciated

    thanks for all the help!

  17. Laysa Says: 

    Thanks! Included this into my code. Hope it works well with Android 4.0

  18. Ryan Gravener Says: 

    I was doing this and for the life of me could not figure out why it wasn’t working.

    I magically found this: http://www.w3.org/TR/html5/offline.html#manifests

    It told me that my webserver mimetype for manifest needs to be supported. So if it isn’t working, make sure your content type for your manifest is text/cache-manifest

    you can see by doing curl -I “http://yourmanifestsite/cache.manifest”

  19. Marco Seguri Says: 

    Thank you so much!

Leave a Comment

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值