I have an Android application that would retrieve data (images+text) from a php remote server and display them in a GridView.
I am doing the operation in the background using Loaders. I have separate connections for images and texts since retrieving images would take longer and I want to display the texts immediately. The texts are encoded with Json on the server after being retrieved from MySQL. On the app, I am parsing the Json Objects and displaying the texts as I need.
The problem is with images. I am not sure if encoding the images with Json would be a good idea. Also the images are saved as blob in the database, in order to encode them with Json I need to use base64_encode() before which is not efficient. I have seen many posts about this, but it’s always a simple example when you have to get one image. In my case I’ll be retrieving up to 30 small-size images.
My question is, I can proceed with what I just presented, but it seems that there should be a better way to do this. What do you think about this? Am I going the wrong way?
Also I was thinking if I can display each image separately in the gridview once it is ready (not waiting for all the images to be ready) just like in the “Google Play App”’s GridView. What approach can I take to achieve this?
Thanks in advance folks!
Best approach in my eyes would be to download the image files as normal image files via a HTTP get request. Make sure it is threaded of course, and have a thread pool that you can queue up requests into, and have 2-3 threads go through and download.
In terms of saving them, I would personally move away from saving to blob in a database, and opt to save them to the persisted storage in your application's private directory. Saving the image files with their filename as their id in the database you have created will be much quicker for loading them back in.
You can also hold a reference to the ImageView, and have it display a place-holder initially, with a successful HTTP request replacing the bitmap of the ImageView with the one you have just downloaded/read in from storage.
You can also do some image caching within the HTTP request you make.
ImageView myImageView = findViewById(R.id.testImage);
URL url = new URL("http://www.website.com/image.jpg");
URLConnection connection = url.openConnection();
connection.setUseCaches(true);
Object response = connection.getContent();
if (response instanceof Bitmap) {
Bitmap bitmap = (Bitmap)response;
myImageView.setBitmap(bitmap);
}
It also may be helpful to lookup the uses of the LRUCache, which performs a lot of caching functionality for you.
Check out this link at the Android Developer site for a good in depth guide to image caching
Edit:
You can use the advice in Robert Rowntree's answer to load bitmaps more efficiently to cut down on your memory use as well. The link provided details loading of bitmaps using less memory, something that would work well if you are creating thumbnails from larger images downloaded over the web and saved off to local storage.
IMO - there are 2 issues , moving the images across the network to the client and getting them loaded.
Assuming that you are using http as the protocol, you should have a multithreaded solution for http as is available in apache httpclient package. That will get the pictures to the phone fast.
Then , you have to present the pics by getting them into memory and a cache. Here you can consider what 'gallery3D' app does with its grid and bitmaps but its pretty complicated to read thru that code.
check out - http://developer.android.com/training/displaying-bitmaps/load-bitmap.html
check out code samples for loading thumbs from bitmaps.
Related
I have an app where I take data from API (some points on map with properties like descriptions, lan, lat, and list of photos) because of offline mode. I am not sure if I should use sharedPreferences or some okHttp cache (or some ORM database). SharedPref is good for small values, not for list of objects. Do you have suggestions/best practices?
Thanks
Store your data in db with image URIs. Store Images in memory cache and retrieve them from their URI. Retrofit doesn't comes with support for image loading from network by itself. If you don't want to go into depth of all this, you can use Glide or Picasso.
Picasso saves full image and can be resized at the time of loading. Glide caches images after resizing. See what fits your case.
Storing and retreiving images directly from database will require too much processing and slow down loading of images especially if you need large images. For more information read check out developers note on Caching Bitmaps and Display Bitmaps Efficiently.
I would suggest you to use response cache if you require the response only to display. Retrofit provides a nice and handy response caching method, you can make use of Interceptors to cache response. hope you are using retrofit latest version 2.1.0. check out this link to get more.
If you wanted to perform some operations like marking favourites etc. you can go for database.
So i´m creating a app in Android which stores images in a external server. I want to know where is better to make the optimization of the image file, in server, or give the non-optimize image to local and then optimize inside the app. Im using mysql for store the images, but if its better to use sqlite server i will change it. Thanks.
The best thing to do here is create an application on your server exposed through an API with query parameters to specify image sizes + caching mechanism.
For example:
www.mywebsite.com/imageloader/file-identifier?width=50&height=50&format=png
then implement a caching mechanism take a look at (https://dev.mysql.com/doc/refman/5.1/en/ha-memcached.html) for mysql on the server for this image using these parameters so the application can quickly return this file each time and not require too much work from the application. This will allow you to request multiple images at specific sizes when you need them for example only as a thumbnail... Or a full Gallery image which can be something much larger.
Additionally you will want to use an Image Library and there are certainly quite a few for Android (to name a few):
Picasso from Square http://square.github.io/picasso/
Fresco from Facebook https://github.com/facebook/fresco
Ion from this Github https://github.com/koush/ion
These can all help you format your images and cache them locally and even downsize the images as necessary.
What am I trying to achieve: Based on some filters by the app user, I want to return a list with text and images.
How am I doing it: I have created a table in Parse and have added a column with object type as 'file'. I have put all the jpg/gif images into that column. (double-click, browse, select image from local computer).
The trouble I am having is, the list takes considerable time (~7 seconds) before it is displayed on my android app.
Is there a better way of handling image data within Parse or should I store images somewhere else (like Amazon S3)?
I am using standard queries for Parse in order to get data, nevertheless, am also checking if there is any code latency. Wanted to confirm if I am correctly handling the image data for back-end or not.
Is there a better way of handling image data within Parse or should I
store images somewhere else (like Amazon S3)?
If your images is not too much or you are using for example(five image) its better to save the into the Assets or Drawable Folder for loading.
and if i correctly knows about this problem, you need to use ProgressBar and one image, before loading the Images in Internet.
Caching images and displaying
Hope this helps.
I am using Parse to store images too, but it's not slow as you said. Since Parse is part of Facebook, I think their infrastructure is the same. There are possible issues:
Internet connection: Slow or on 3G?
Images: files are big?
Let me know which case you are in.
If you just display thumbnail images, I suggest you to process it before saving to Parse by writing Cloud function as describe on their blog. The you just need to use generated thumbnails on your listview/gridview
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 have an android application, that will call a SOAP web service for some data.
For the purpose of this question, we'll assume its data about cars.
I've got as far as returning text data about the car (make, model etc), that is the easy part. I'd also like to return an image of the car some how.
So far, I see two viable options :
Retrieve the image in the SOAP response (don't even know if this is
possible)
Retrieve a URL in the SOAP response that points to the image,
perhaps a URL to a web image
Could anyone please give advice as to what is a robust solution for achieving this?
Thanks
Option 2, definitely. If you do option 1, you're limited to displaying only after you've completely downloaded the entire message, including the encoded images. That can take a while. On the other hand, if you just include URLs, you can download the message, render your UI, then download the images and update those image views dynamically as the images finish fetching from the web. This results in a much more responsive UI, especially in a mobile environment where your data connection may not be as fast or reliable.