Image downloading and caching with Picasso Library
Picasso Library is very powerful tool for avoiding Bitmap handling in your application. It takes care of displaying image efficiently in ImageView from local sdcard, network or application resource. All of this can be done in single line of code.
If you are a self-do android programmer, you will take care of same task writing several lines of code.
1. Using AsyncTask
for downloading images in background.
2. In addition to background thread, you will keep track of downloads for particular ImageView in order to handle orientation change or if user scrolls your list/grid view.
3. To avoid downloading image, you would prefer to have cache for your downloaded bitmaps. You will implement LRUCache<String, Bitmap>
for smooth caching of downloaded images.
Picasso library provides you power to handle all of the above task with just single line of code. It will take care of following functionalities by itself.
1. Handling ImageView
recycling and download cancellation in an adapter.
2. Complex image transformations with minimal memory use. You can resize your bitmaps to fit nicely in your ImageView without any hassle.
3. Automatic memory and disk caching.
Sample Picasso Application
1. Add gradle dependency in build.gradle file.
compile ‘com.squareup.picasso:picasso:2.5.2’
2. Add Internet permission in application manifest file since we will load image from network as well.
<uses-permission android:name=”android.permission.INTERNET”/>
3. Prepare your layout view for showing images loaded by Picasso. I have taken 3 ImageViews to show loading images from network, application resource and sdcard. Modify your /res/layout/activity_main.xml as below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.androidsrc.picassoapplication.MainActivity" > <FrameLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" > <ImageView android:id="@+id/networkImage" android:layout_width="match_parent" android:layout_height="match_parent" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:layout_marginTop="10dp" android:gravity="top|right" android:text="Newtwork Image" android:textAppearance="@android:style/TextAppearance.DeviceDefault.Large" android:textColor="@android:color/white" /> </FrameLayout> <FrameLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" > <ImageView android:id="@+id/appResourceImage" android:layout_width="match_parent" android:layout_height="match_parent" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:layout_marginTop="10dp" android:gravity="top|right" android:text="App Resource Image" android:textAppearance="@android:style/TextAppearance.DeviceDefault.Large" android:textColor="@android:color/white" /> </FrameLayout> <FrameLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" > <ImageView android:id="@+id/localFileImage" android:layout_width="match_parent" android:layout_height="match_parent" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:layout_marginTop="10dp" android:gravity="top|right" android:text="Local file Image" android:textAppearance="@android:style/TextAppearance.DeviceDefault.Large" android:textColor="@android:color/white" /> </FrameLayout> </LinearLayout> |
4. In our java source code of activity, we will take references of ImageView’s in layout file. For these views, we will load images in single line of code. Refer setImagesUsingPicasso()
for details. Make sure you have placed one png file named “picasso_demo_image.png” in sdcard root directory. Otherwise it will show error image as specified.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
package com.androidsrc.picassoapplication; import java.io.File; import com.squareup.picasso.Picasso; import android.app.Activity; import android.os.Bundle; import android.widget.ImageView; public class MainActivity extends Activity { ImageView networkImage; ImageView appResourceImage; ImageView localFileImage; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); networkImage = (ImageView)findViewById(R.id.networkImage); appResourceImage = (ImageView)findViewById(R.id.appResourceImage); localFileImage = (ImageView)findViewById(R.id.localFileImage); setImagesUsingPicasso(); } private void setImagesUsingPicasso() { //Set network Image Picasso.with(this).load("http://cs2guru.com/samples/images/AndroidSRC_SampleImage_1.png").fit().into(networkImage); //Load from app resource Picasso.with(this).load(R.drawable.app_resource).fit().into(appResourceImage); //Load from local file Picasso.with(this).load(new File("sdcard/picasso_demo_image.png")).fit().error(R.drawable.ic_launcher).into(localFileImage); } } |
5. Build and run your application. You will observe images loaded into your views.
Picasso perform efficient bitmap transformation. You can define height, width and scale type for better fit in your view.
1 2 3 4 5 |
Picasso.with(context) .load(url) .resize(height, width) .centerCrop() .into(imageView) |
Picasso also supports PlaceHolder images. In case of error in download, it will try for total of 3 times and finally error placeholder will be shown.
1 2 3 4 5 |
Picasso.with(context) .load(url) .placeholder(R.drawable.user_placeholder) .error(R.drawable.user_placeholder_error) .into(imageView) |