I have been trying to enable caching in Android WebView but every config I saw on SO ends in failure.
Here is what I have:
I have a webpage which has an Iframe inside that loads 10-12 pages in a loop all the content in those pages have Cache-Control: max-age=86400 header.
If I load these pages normally in a browser they work and the pages are cached.
So here is the config that I have
getSettings().setJavaScriptEnabled(true);
getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
getSettings().setDomStorageEnabled(true);
getSettings().setMediaPlaybackRequiresUserGesture(false);
getSettings().setAppCacheEnabled(true);
getSettings().setAppCachePath(context.getCacheDir().getAbsolutePath());
getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);
These settings work for media playback and enabling js
EDIT
I built a new app and tried loading google with the loadUrl method and reloaded that with a button while the net was off, it was able to reload the page without internet it means it cached that page.
So the issue is that webview is not caching pages which are being loaded by the page.
If anyone knows how we can cache the content which is loaded by webview page loads it would be a great help.
-Thanks
So after a series of detailed tests on our iframe and Android device, I came to realize that WebView does not cache files which are bigger than a particular size.
One of my pages which were being loaded by the iframe had a video of 30mb which was not getting cached and was resulting in huge data consumption. (as it was getting rendered every 2 mins)
I reduced it to 10mb and it still did not cache it finally I reduced it to 980kb and it started caching.
I am not sure about the caching limit per file for WebView but I came across an interesting bug here which states after Android 4.3 the total cache limit was hardcoded to 20mb which we can find in this file on line 98.
If anyone knows where these limits are documented do let the community know by replying here.
This code solve my problem, hope help you too:
webView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
EDIT: Also you don't needs to these lines:
getSettings().setAppCacheEnabled(true);
getSettings().setAppCachePath(context.getCacheDir().getAbsolutePath());
Remove them and check one more time. AppCache setting not related to type of cache that you want.
Related
I'm running my app that has webview on different activities, they are loading online pages, the issue is that everytime the activity opens the webview takes a couple of seconds to load the page and the page is not available offline.
I was looking for a solution where the webview would always be accessing an offline copy of the website, and the app would download and replace the local website every 24 hours.
I thought it would be simple
Thanks
I see a couple potential solutions to this problem.
Change WebView Cache Mode
The first and simplest would be to change the cache mode of the WebView so that it is forced to load from the cache. This way it will try to load from the cache, and if any resources are not cached, then it will do a network load. This can be simply accomplished by using:
WebView webView; // initialized somewhere
webView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
Theoretically, you could use LOAD_CACHE_ONLY if the WebView has already loaded once and it doesn't need updating, otherwise you could use LOAD_DEFAULT. Using the LOAD_CACHE_ELSE_NETWORK should definitely speed up loading time, but it might still load some stuff from the network.
However, in practice, I have seen the cache settings not work as consistently as I would like them to.
Utilize WebView.saveWebArchive()
Another more robust solution would be to use the web archive capability that the WebView has. I have not used this solution myself, but you can read about it in this question.
Basically, you can save the contents of the WebView using the following:
WebView webView; // initialized somewhere
webView.loadUrl("http://blahblahblah.com"); // URL to save
Context context = this;
String pathFilename = context.getFilesDir().getPath() + File.separator + "savedWebPage.mht"; // You can use any path you want
webView.saveWebArchive(pathFilename);
Then you can load the saved archive file by using:
webView.loadUrl("file://" + pathFilename);
Please note that I am leaving out the logic for handling when to load from the website and when to load from the archive file, that's up to you how to handle it.
So that's about it, I want webview to download and cache multiple pages when the app is opened so that they're saved for offline use. They're only going to be a few kilobytes each and there's only going to be about 10 of them, we're talking less than 100kb all together, but I want to make sure all the info is up to date when the app is open. How would I do go about doing this? Just somewhere to start would be nice.
Edit: assume internet connection at first, but then this stops and there's no internet after the caching is complete.
You can create a WebView and make it not visible and load the resources here.
Is it possible to cache a list of website urls, image urls etc without opening them first in a webview? I have a list of img urls coming from a feed that i want to cache on download. i have already posted a question about this but have gotten no response here is my previous question. (https://stackoverflow.com/questions/21831464/cache-image-urls-android)
It's not possible to drop things into the WebView's cache directly. The only way that would not require preloading in an "off-screen" WebView (which is totally possible, btw.) would be to download the images yourself and serve them back to the WebView using shouldInterceptRequest.
I would recommend caution with the shouldInterceptRequest-based approach though. It's easy to hurt performance when using shouldInterceptRequest (see here). Also, you need to take care of removing stale images from your 'cache'.
I am using android webview in my app for browsing. All the pages load fine. no issues. But as I keep browsing (opening links) the memory keeps increasing. For example: 3 pages navigated its 60 mb and after it reaches a point the app crashes.
Now, these are regular websites like cnn.com, gmail.com, gap.com etc
Any ideas or pointers?
Thanks!
You should use caching to avoid such memory leaks!
loaded images can be cached on disk and loaded incrementally.
Here is a generic caching library together with example usage >>
I want to load a webpage, and if it was already loaded before and not modified then load it from cache. If it is found to be modified, then clear this page in the cache and reload.
How can I do this?
Write the webpage into the cache
Find the webpage in the cache
Show the webpage from the cache
Clear the cache and load a new version if the page was modified
Please help me. It would be awesome if can show me the code for each of the above.
Best regards.
If you are ok with using Webview then LOAD_NORMAL is for u.
webView.getSettings().setCacheMode(WebSettings.LOAD_NORMAL);
webView.loadUrl(HELPER.SERVER_BASE_LINK + "ads/s_image" + (i+1) + ".jpg");
It uses cache to load the webpage unless the page is modified, which is also mentioned in the description of setCacheMode();
http://developer.android.com/reference/android/webkit/WebSettings.html#setCacheMode%28int%29
It takes a few minutes (within 5) to reload the modified page. It is probably the poling time of Android for checking expired pages. I have tried it myself, but I felt bugs in it, sometimes it just doesn't load the cache. It might be that android is taking my cache back too quickly, which is usually not the case.
Using cache with browsers will have some similar method.