Android Picasso Save Image Tutorial

Loading an image from a URL into an Android application and managing it is not a trivial task. You have to do several things like network operations, creating and extending cache, loading the image and more. On its own Android SDK doesn’t provide the tools to make this process easier. Fortunately, several open source libraries exist for this purpose. I came across two great ones (Picasso and Universal Image Loader) while building my images related Android app.

I tried Universal Image Loader (UIL) first mainly due to its popularity. It all went well until it failed to do very important task for my app (i.e. save image on disk). After trying for 2 days, I came up with a solution which at most I can say was rough. So, I thought to give Picasso a try and fortunately it helped me achieve this task quite easily. Honestly, I don’t think UIL is a bad library either but its developer didn’t put much effort regarding image saving process.

So, lets start with our Android save image tutorial now. I will only explain a portion of my app’s code here but it is sufficient for this tutorial. I can’t explain my whole app for obvious reasons!

Prerequisites:

  1. Create new Android project using your favorite IDE (I’ll using Eclipse).
  2. Download Android Picasso library from here.
  3. Put the downloaded jar file into your project’s “libs” folder.

Tutorial:

First create a new layout file in your Android project. You can do it by opening res/layout folder and then clicking “New Android XML File” in eclipse’s toolbar. Name the file “image_detail.xml” and click on Finish. Open the newly created file in its source view and put this code into it.

image_detail.xml

This layout file defines a FrameLayout with two direct childrens – an ImageView element and a ProgressBar element . I decided to use a FrameLayout so that a progress bar is displayed while the image is loading. Note that I set the visibility of progress bar to visible so that it will visible on the start of the activity using this layout.

Moving forward, create a new java file in src/ folder named “MainActivity.Java“. It might already be present so use that. Put this source code into the file.

MainActivity.Java

I am extending my “MainActivity” from “ActionBarActivity” because I’m using the Appcompat library. You can simply extend from “Activity” class if you like. Then I declared ImageView & ProgressBar objects and a String variable containing the URL of the image. In my app, I was getting this from a data source but I preferred to just use a URL for the sake of simplicity here.

In the oncreate method of my Activity, I’m setting its view from the layout file  “image_detail.xml”. Then I’m referencing the “image” ImageView and “loading” ProgressBar from the view and putting into corresponding objects we created earlier. Now, the Picasso library comes into play. In just few lines of code, it downloads the image from the provide URL, caches it and displays it in our imageView. I’m actually using the library twice here which I will explain now.

First time, I’m calling Picasso with “this” which is the current activity context, then loading the image from the string “currentUrl”, setting the error image to “error_detail” drawable in my res folder and finally putting the image into our “imageView”.  While loading image into the imageView,  I’m calling an EmptyCallback method to handle our progress bar which we originally set as VISIBLE. Here two scenarios are possible:

  • Image gets downloaded and is loaded into the imageview, then “onSuccess” method will be called setting the progress bar visibility to GONE.
  • Image didn’t downloaded for some reason and thus can’t be loaded into the imageview, then “onError” method will be called again setting the progress bar visibility to GONE. However,this time Picasso will load the error message drawable “error_detail” in our imageView.

Second time, I’m calling Picasso to load the image from “currentUrl” and putting it into “target”. (Image will be loaded from cache now as we had called Picasso before).  We are using the Target class provided with the Picasso library to convert our image to bitmap. It actually has 3 three methods but we are just concerned with onBitmapLoaded as we only need to save the image to disk when it is loaded. I created a new thread here because it was causing threads issue and crashing my application. Then in our new thread we are using runnable to create a new file named “actress_wallpaper.jpg” on the disk and puting our bitmap into it.

That’s it. We have successfully saved the image loaded from Picasso library onto our disk space and retained its full quality. We can use this image to do further things like share with other apps or setting as wallpaper (If anybody requests, I’ll make a tutorial for it).

Note: Picasso uses the http headers to cache the image so it may not be stored for long. After sometime, it tries to load the image again from server instead of the cache. As a workaround, use “OkHttp” library made by the same people as Picasso. Just download its jar from here and put it into your project’s “libs” directory. Picasso will use it by default and cache will be stored longer.

Related Posts

5 Comments

  1. Fred
    May 20, 2014
  2. Fred
    May 21, 2014
  3. gill
    November 19, 2014
    • Saurabh Bansal
      November 19, 2014

Add Comment