It's an APP with kind of gallery context. Using REST I am receiving (Volley) JSON which contains information about place and few links to the pictures. Because there is about 60 places, so the caching form PICASSO is not enough. Data is stored in DB so I my idea was to insert an image to the database as byte stream
. It's done, but in not so good way, presented below. Code inside AsyncTask
.
@Override
protected Bitmap doInBackground(Void... params) {
try {
return Picasso.with(context)
.load(site.getImageURL())
.get();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
try {
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
} catch (Exception e) {
e.printStackTrace();
}
site.setImageBytes(stream.toByteArray());
db.openForWrite();
db.updateSite(site.getId(), site);
db.close();
}
My question is how to make it efficient, do you know better way to do that? I tried to callback
to Picasso to add image to the DB onSuccess
, but it require the view as a first argument.
Maybe there is a good ways of saving images to SD card, and replacing HTTP link with location of image on SD card.
Or caching image to the disc directly?
Answers. Hi, These two ways are both ok. My suggestion is to store images into sql database if there are no much more images, otherwise, it's better store them into file system because you can store them no matter how many there are.
A database gives you the opportunity to store photos and other small images in a database table. You can create such a database table for example when you want to create an online photo album with descriptions of your photos. Storing images in a database table is not recommended.
SQLite is a opensource SQL database that stores data to a text file on a device. Android comes in with built in SQLite database implementation.
Inorder to store images to android SQLite database, you need to convert the image uri to bitmap then to binary characters that is, bytes[] sequence. Then set the table column data type as BLOB data type. After retrieving the images from DB, convert the byte[] data type to bitmap in order to set it to imageview.
There are several issues to note here:
onPostExecute
runs on main thread. Not a good place to do disk IO. UI will freeze from time to time when images are being displayed.
SqLite blobs are faster than plain disk files only for limited sizes (Benchmark). So, large files are better stored on disk.
Using Picasso is advised if you want cached lazy loading on images. Problem is that Picasso won't allow to easily use your custom "DB as a cache" solution. It uses a general purpose HTTP cache. Hence, cached files may be periodically be invalidated and cleaned out.
If you want completely customizable HTTP and image loading, try something like Volley.
I would suggest you to go with caching, consider using Universal Image Loader library by Sergey Tarasevich (GitHub)
it allows detailed cache management for downloaded images, with many configurations
- UsingFreqLimitedMemoryCache -> The least frequently used bitmap is deleted when the cache size limit is exceeded.
- LRULimitedMemoryCache: -> The least recently used bitmap is deleted when the cache size limit is exceeded.
- FIFOLimitedMemoryCache: -> The FIFO rule is used for deletion when the cache size limit is exceeded.
- LargestLimitedMemoryCache: -> The largest bitmap is deleted when the cache size limit is exceeded.
- LimitedAgeMemoryCache: > The Cached object is deleted when its age exceeds defined value.
- WeakMemoryCache: -> A memory cache with only weak references to bitmaps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With