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'.
Related
I am very new to Android. I am trying to create a social app which contains lot of images and some metadata. It has a screen which is similar to the feed on Facebook. I want to make this screen as smooth and standard as possible.
Here are the libraries I am using: OkHttp, Picasso, Retrofit, Gson.
Right now, I am fetching all the json in one go, since I have seeded dummy values in backend and the response is small enough. But, in future, it will have the previous and next fields to limit the json response.
Some of the questions that I have right now:
I am using Picasso with OkHttp. Does that cache images in disk too or only in memory?
What are the best practices on caching the feed? Since the majority of content is images, should I just let Picasso handle the caching or should I cache some items on my own? Heard about DiskLruCache library from JakeWharton but not tried it. Should I go with it?
How to keep some feed contents(like 3 or 4) in either direction of scroll in cache so that scrolling appears smooth and that images don't start loading after coming in the view.
How to automatically handle json response using previous and next fields when the user scrolls all the content that was fetched in this one go. Basically I want to trigger requests based on the number of contents scrolled based on cursors.
Suppose there is a like button and the user click it, should I change the number of likes in the UI and side by send a POST request to update counter or should I send the request and wait for the updated counter from server before updating it in the UI?
I have already gone through the source code of Instamaterial and got to learn some amazing things. But it does not demonstrates the whole backend integration.
I just want to know if there are any other open source apps which I can study or learn from. If you know any tutorials that would help too. I just want to make the app experience as smooth as possible and want to learn some best practices.
This will cache to disk as well as memory. If you set Picasso to debug mode it will display an indicator that describes where the image was loaded from (memory/disk/network)
If you don't mind Picasso having control over how long things are cached etc. then it should be fine to let it handle the caching. I'm also pretty sure that Picasso uses DiskLruCache
If your main concern here is the images, they will all be cached and shouldn't need to load after they have done so once (until it updates). You can also register a callback with Picasso in order to change the logic around showing or hiding placeholders.
I think that what you are looking for is a scroll listener on your listview (I assume you are using a list view). When it gets past a certain position (5/6) start loading the next 10. If you are using a recyclerview you can do this with the onScrollStateChanged function in the scroll listener and use the LinearLayoutManagerto call findLastVisibleItemPosition
It shouldn't really matter which approach you go with. If you think that it will take a long time for it to update the server counter (which it shouldn't) then it is probably best to update it locally first.
1.I would suggest you to checkout Image Management Library by Facebook that is Fresco that is pretty awesome and mature as compared to other Image Loading Library.
2.Fresco handles all the things caching of images with 3 Tier architecture ( BITMAP_MEMORY_CACHE, ENCODED_MEMORY_CACHE and DISK_CACHE). It also reduces OOM(Out Of Memory) issues. When image in a view goes out of screen it automatically recycles the bitmap, hence releasing the memory.
3.For that you have implement Pagination, yeah for sure you might have to send the previous record item position or index, so that you can fetch the items succeeding it.
4.For providing user the smooth experience in your app, you should increment the counter and send the post request to your backend simultaneously.
you can also checkout this tutorial Facebook like Feed.
I would prefer you some approaches for some of your questions:
For handling JSON:
You can use library called Retrofit, so adding and removing stuff in server side, will be easy to handle in your android client side. Just removing or adding variable in a Java class will be enough!
For cashing images:
I suggest you to use Fresco, facebook library, It will ease your job alot. since it can handle rounded corner conversions, downloading Progress bars, Circular images and many more features. So, Not only handle the Memory and Disk cashing for you, but also works better with different image formats.
(I used picasso in my last project, Some pictures and some URIs did not work well, I tried Picasso, Glide, and Universal Image Loader, on exactly same image and same link..ONLY Fresco could work fine for me)
It is not exactly answer to your questions, however, i wanted to share my experience with those libraries that may help you.
I am developing Android app now where I need to store image Url in DB for each object and then load this image from the web (if connection is on) OR get it form cache (if not).
Picasso seems to be best lib for handling images in Android, so I starter using it. But I can not get how do I use it properly for my case. Even more - Images strangely are loaded into views right after they are first time get from API but if user starts app again, we can see placeholder only (even with internet connection on). Can someone suggest a solution or at least any kind of idea of best way to do this?
My code in Adapter (is is also same in ShowActivity):
String img_url = item.getImage(); // img_url is valid image url
Picasso.with(mContext).load(img_url).placeholder(R.drawable.plchldr).fit().centerCrop().into(holder.image);
I tried to use Picasso at the start as well, and found out that their caching system is horrible.
It would cache some images i downloaded, but not others, and would therefore leave alot of images with placeholders.
I suggest you try Universal-Image-Loader (https://github.com/nostra13/Android-Universal-Image-Loader). I'm currently using this to cache all images in my app, and it works flawlessly (Around 200 images atm).
Finally got the problem - API is returning valid image url BUT actually it (image) is hosted on S3 cloud and it is expiring till the user loads application again. So, actually saving expiring image URL is useless in this situation. I am not sure what will I do here (it seems that the only way here is hard one - storing images on SD as Bitmap). But I just wanted to tell this for those who will get similar issue.
I just finished reading few some sparse tutorials on caching/offline and about making an Apps responsive when the user is not connected to the internet. It was quite interesting cause I have being wondering how some Apps have being doing that cause I was thinking it was some database manipulation.
I am relatively new to the caching mechanism and I really want to implement it in my next project cause I am still learning.
The few tutorials I have read talks about caching static files like pictures, .css files, .js files etc
My question is this;
**Question 1**
How do I cache Dynamic Files e.g I have an Apps when a User want to view their profile, I normally implement it by sending an Ajax request to the server to populate the profile page with pictures and other profile details (texts). How Do I cache these texts and pictures since they are dynamic?
**Question 2**
I am using different page (index.html, profile.html) JQuery Mobile mechanism, will this affect caching in any way because I have to refresh the page every time I am navigating to a new page so as to show my styling correctly?
This question may sound really noob but I really want to learn and I have read a lot about caching but these question were not addressed. I just hope somebody helps. thanks...
Answer is given based on my knowledge so far.
1) You can store / cache things with localStorage It's preety basic so won't take a lot of time or coding or mechanism to implement. Profile data, image as encoded string can be saved in localSorage. First you will save the profile data in localStorage. Then next time after app starts you can load data from the localStorage and also in the mean time you can make a async ajax call to server to check if data is modified. If so, then you can bring that data again and update localStorage.
2) If you use localStorage then page transitions won't be a matter until you reach the localStorage size limit of 5 mb.
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'm making an android app, here the images are getting from Cloud, is it good idea to download images and save it & use it further. Or download images every-time user uses the app, what idea you prefer is the best?
Because downloading images always is slow & its bad i know but at some point if the images are updated then how to get to know about it?
You should definitely cache your downloaded files!
Do it in your internal app directory where only you do have access to (or otherwise external storage, thats still ok).
Bandwidth and connections are always expensive and should kept low as much as possible.
So your user can see images fast even on a bad connection and your app doesn't waste his valuable bandwidth of a users data plan.
Maybe this could also help you:
https://github.com/novoda/ImageLoader
http://www.androidhive.info/2012/07/android-loading-image-from-url-http/
Make it easy on yourself and use something like Android Smart Image View. It takes care of loading and caching, and it's just about a drop-in replacement for Android's ImageView. Universal Image Loader is another alternative, more configurable, but not as quick to implement.
I used https://github.com/nostra13/Android-Universal-Image-Loader
but I think you not want only download and cache.
these no trick ,if you want check weather the image update or not, you can add metadata for image, just like md5 .
in html and browser, you can set expires header for a image:
enter link description here
but in android app, you control all yourself.
Downloading images and saving them is probably the best way to do it because you don't want to download the same images over and over. If the images are updated you can delete the older one and download the new ones. Just make sure you don't download/save a million images. Take a look at this library. It has a built-in cache on sdcard/external sd.
Downloading images from the net for display, with possible requirement of caching is a very common problem that many people have solved, you can try these solutions to see which fits you:
Ion (https://github.com/koush/ion) - very flexible and feature complete, plus it can download more than images but JSON, Strings, Files, and Java types as well. The part that I really like about this is that it can automatically cancel operations when the calling Activity finishes, so users don't waste time & bandwidth downloading images that will no longer be displayed
Universal Image Loader (https://github.com/nostra13/Android-Universal-Image-Loader) - equally capable for most use cases but for downloading/caching images only