Site icon Treehouse Blog

The Missing Widget in the Android SDK: SmartImageView

The Missing Widget in the Android SDK: SmartImageView

Displaying an image from the web in an Android app is unnecessarily hard to do the right way. You need to download it byte by byte from the Internet, store it in a Bitmap object, and then set this Bitmap as the content of the ImageView.  And that’s just the minimal solution; you also want to cache the image so you don’t need to download it each time the ImageView is created, and you ideally want to perform the download off the main UI thread so that your app remains responsive for the user.  The last thing you want to do is spend a long time downloading an image over a poor network connection and leave your app in a locked state until it completes.

While this isn’t insurmountable, it seems like a common problem that should be addressed in the ImageView API.  The first few steps mentioned above–downloading, storing as a Bitmap, and updating the ImageView–can be done using the setImageURI(Uri uri) method. But the documentation for that method states:

“This does Bitmap reading and decoding on the UI thread, which can cause a latency hiccup. If that’s a concern, consider using setImageDrawable( or setImageBitmap( and BitmapFactory instead.”

I’m perplexed that this alternative solution isn’t available in the SDK, but thankfully a few independent developers have made alternatives available as open-source software that we can use in our own applications.  The best I’ve found is a widget called SmartImageView that’s available from James Smith (@loopj).  Let’s take a look at an example for populating an ImageView using somebody’s Twitter profile image.

Using SmartImageView Instead of ImageView

The source code for SmartImageView is available from GitHub, but to use it we just need to download the latest JAR file from the SmartImageView page. Once downloaded, we need to add the JAR file in the “lib” (or “libs”) directory of our Android project.

Before we forget, let’s make sure that we’ve added the permission in our AndroidManifest.xml file to access the Internet:
<uses-permission android:name="android.permission.INTERNET" />
Now, let’s start with adding a SmartImageView in an XML layout, just like we would do with a normal ImageView. There are two important things to notice here. First is to remember that, when using custom UI components, we need to include the full package name, like Second, because SmartImageView extends ImageView, we can use all the same attributes and methods of ImageView in addition to the added functionality.
<LinearLayout xmlns:android=""
    android:layout_height="wrap_content" >

        android:scaleType="fitCenter" />


Now, all we need to do is get a reference to the ImageView from the layout like normal and call the setImageUrl() method with the URL as a String parameter:

public class MainActivity extends Activity { 
    public void onCreate(Bundle savedInstanceState) { 
        SmartImageView profileImage = (SmartImageView) findViewById(; 

That’s it! The SmartImageView will download the image asynchronously and load it when it’s complete.  It will also cache the image for reuse so we don’t need to re-download it each time we run our app!

If we want to clear out the image, we just call the setImageUrl() method with a blank URL. We can optionally provide a second parameter: the Resource ID of a default image to use instead:

profileImage.setImageUrl("", R.drawable.ic_launcher);

We can also use the SmartImageView to load an image from the user’s Contacts app, which makes use of contact data exposed by an Android Content Provider:


There are a few other solutions like this, but SmartImageView is so easy to setup and use, and it has worked pretty reliably for me so far. If you know of any similar libraries that are as easy as this, let us know in the comments!

Exit mobile version