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.
Related
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.
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.
In an Android WebView, I would like to display websites and download the full HTML with all images from those websites to the device's storage.
As the WebView downloads all assets of a page in order to be able to display it, it would be redundant work if I loaded the page in the WebView and afterwards download the HTML and images again, right?
So I thought you could maybe access the contents that the WebView downloaded and just copy them to the device's storage. Is this possible?
According to this page, you can set up JavaScript interfaces and then call some JavaScript statements like this:
webView.loadUrl("javascript:doSomething()");
So I could get the page's HTML if I just used JavaScript's document.innerHTML or document.getElementById('theID').innerHTML.
And for the images, is there an easier solution than to use JavaScript? The problem is that I don't just want the URLs but the loaded resources. The WebView did already download all assets, so the question is if it exposes access to them in some way.
As described in this question, it seems to be possible to get images using context menu events. (Maybe even background images.) But is there a solution that does not require user actions and saves all images in batch, preferably without downloading them once more?
In short: no. There's no API to access the downloaded resources from the WebView from Java. You'll need to roll your own solution.
In the case of images, the only way I can think of to avoid re-downloading the resource would be to write some javascript that copied the image once it was loaded into a <canvas> element and then read the bytes back as a data URL. You'd then be able to recreate the image on the Java side from that data URL (by passing it to Java via a JavaScript interface in your WebView) and save it to disk or work with it otherwise.
These links would probably be helpful to you:
Canvas and toDataUrl:
http://www.html5canvastutorials.com/advanced/html5-canvas-get-image-data-url/
WebView JavaScript Interface: http://developer.android.com/reference/android/webkit/WebView.html#addJavascriptInterface(java.lang.Object,
java.lang.String)
I want to pre load a web page in Android. The web page contains both text and graphical elements. The web page will be displayed in the future in an Activity which has not been created yet.
As far I understand it a WebView for example has to be tied to an Activity, thus it's not possible to use a WebView for this task.
Anyone got any suggestions which does not involve parsing the html page and downloading all the elements "manually"?
According to android's documenation: For obvious security reasons, your application has its own cache, cookie store etc.—it does not share the Browser application's data.
So we can make use of the above info in a smart way by doing this:
Whenever you want to start loading your website, create a new WebView object and request the url from it. the code will look something like this:
WebView view = new WebView(context);
view.loadUrl(myBigWebSite);
Android will cache that webview data and when you request loadUrl from another activity it should be already loaded.
// in your WebView activity
myWebView.loadUrl(myBigWebSite);
For more about webViews visit the documentations page : WebView doc
You can download all required files (images, etc) into some folder on a network thread and then use something like
webview.loadUrl("file:///my_cached_folder/index.html");
Images will also be picked from this folder, if referenced and present. Read about opening local files on webview here.
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.