-->

Solving the Android Image Loading Problem: An Updated Guide

2017-09-12

Toward the end of the Android Essentials bootcamp, students learn to load images from the web into a RecyclerView. As an instructor, it’s one of my favorite chapters because it teaches some of the fundamental pieces of Android including Handlers, HandlerThreads and Loopers.

However, I also warn students that it is not meant as a complete guide for loading an image in an Android app. It doesn’t cache images, barely supports request cancellation, and the solution is too complicated and custom for what is a very common task in Android. Four years ago, we wrote a post on Volley vs. Picasso, but today there are newer options and limitations that we should consider.

In this post, I’ll be comparing the three most popular image loading libraries: Picasso, Glide and Fresco. All three have very similar features but differ from each other in small ways. This post aims to show you what each is capable of in order to help you confidently choose the right one for your needs.

Loading An Image

Let’s first take a look at what it’ll take to load an image with a placeholder in each library. We’ll talk about the differences in more detail. You can see this code running in an adaptation of our PhotoGallery exercise from the book here.

Picasso and Glide are very similar and use a simple syntax to load the image:

Picasso.with(getContext())
        .load(galleryItem.getUrl())
        .placeholder(R.drawable.placeholder)
        .into(mImageView);
GlideApp.with(getContext())
        .load(galleryItem.getUrl())
        .placeholder(R.drawable.placeholder)
        .into(mImageView);

In order to access request options like placeholder() in the new Glide 4.0, you will also need to add a generated API and declare the following class:

@GlideModule
public final class MyAppGlideModule extends AppGlideModule {}

And that’s all! Compared to the 100+ lines of code we cover in Android Programming: The Big Nerd Ranch Guide, this is a wonderful improvement. Both Picasso and Glide first fetch an instance of the library and then allow you to specify the URL of the image to load, a placeholder while loading, and your target ImageView. From there, the libraries will handle spawning a background thread, loading the bitmap, and displaying the image it in your ImageView when it’s ready.

Fresco requires a couple more changes to your layouts and code. To start off with you’ll need to initialize the library in your application subclass by calling:

Fresco.initialize(context);

Next you will need to use their special view class, called SimpleDraweeView. In your XML layout it would look something like this (notice that we can specify the placeholder in XML):

<com.facebook.drawee.view.SimpleDraweeView
    android:id="@+id/simple_drawee_view"
    android:layout_width="match_parent"
    android:layout_height="120dp"
    app:placeholderImage="@drawable/placeholder"/>

Finally, in your code you can simply set the SimpleDraweeView to load in your image:

mSimpleDraweeView.setImageURI(galleryItem.getUrl());

Loading Extras

Where all three of these libraries shine is in the features provided behind the scenes. They all keep a local cache of images downloaded, allowing subsequent requests to the same image to simply load from memory or disk instead of incurring another network hit. They each have their own implementation of an LRU cache for in memory and local storage that will clear out entries as memory or storage space is required. Fresco, on Android API level 19 (KitKat) and below will store the bitmap cache’s data in the ashmem heap, not in the Java heap, according to their documentation. “This means that images don’t force extra runs of the garbage collector, slowing down your app. Android 5.0 has much improved memory management than earlier versions, so it is safer to leave the bitmap cache on the Java heap”. That being said these implementation details are largely behind the scenes, and if you require customization, all three provide an API to supply your own cache implementation.

In our PhotoGallery example we use all three in a RecyclerView which adds another problem to image loading. If the user flings very quickly, views will be recycled and reused for rows further down the list. What happens if a view has multiple calls to load a URL to the same ImageView? All three libraries here will manage this case for us. This means keeping track of requests made to the same target view and canceling any previous request made so as to not waste network resources on an expired request. What would previously be a multithreading nightmare is now automatically handled using these libraries.

Finally, all three libraries have image transformation support. If you want to apply a resize, crop, greyscale, etc. to your image as it loads, they each provide an API to define your own transformation to the loaded bitmap. Picasso and Glide each have examples of how to use their transformation APIs, and due to their popularity, you can usually find an example of a transformation you need. For two examples, check out here and here. Fresco has a little more built in when it comes to simple transformations, but if you need more, take a look at their documentation on postprocessing.

Where They Differ

The libraries begin to differ in the image formats they support. Glide and Fresco allow you to load in a GIF image and have it animate in your image view, while Picasso will simply load in a static bitmap of your GIF. Fresco is also the only library that supports WebP images on older versions of Android where support is not natively available. Glide and Picasso only support what is natively supported by the OS; take a look at the documentation for more information on what is available in Android.

Glide adds in some extra support around the Android lifecycle. Glide’s with() method can take more specific fragment or activity instance, which will tie the image loading call to that lifecycle in order to intelligently stop, start and restart requests. Glide recently released a major version change from v3 to v4, so samples may need to be migrated according to the changes outlined here.

Fresco was created as a result of Facebook’s Android development work, which required a large amount of image loading and better performance on low end devices. We mentioned the difference in image caching locations for Android versions below 5.0 that help achieve this improved performance. Fresco also supports the streaming of progressive JPEG images, which allows a low resolution version of an image to load first and gradually improve the quality as more information is downloaded.

The method count of each library can also be a deciding factor for your project. Android applications have a method limit of 65,536 methods before things start to get messy, requiring multidexing of your app or applying proguard to your application. Picasso is quite concise, adding only ~850 methods to your application. With Glide we start to see a bigger footprint, adding ~2,800 methods to your application. Fresco has the biggest impact of them all, as ~5,800 methods are included with the dependency. This can be one of the more important factors in choosing a library, so if you don’t need animated GIFs or some of the other Fresco features, Picasso may be the right choice with its smaller method count.

All three also differ in how they are licensed. Picasso uses the Apache License 2.0, common to many Android 3rd party libraries and used within Android itself. Glide uses a BSD 2-clause. Finally, Fresco uses what Facebook has been calling the Facebook BSD+Patents License. This combination of license and patent declaration has been under close scrutiny recently by the community; here is an article that explains Facebook’s point of view.

And the Winner Is…

You can probably guess by now that I do not have an answer to this question. Each has its strengths and features for you to consider. In our consulting projects at Big Nerd Ranch, we find ourselves using different libraries for different applications depending on what the needs of the client may be. Take a look at the PhotoGallery sample showing each one in action, tinker with it a little bit and see which one fits you best.

For more information on how this works within your Android app, consider enrolling our Android Essentials bootcamp. We host one a few times a year at our Ranch locations, or we’ll bring our instructors to teach your entire team through our corporate training program.

2017-09-12

Yazıda Geçen Linkler
  1. bignerdranch.com
  2. github.io
  3. frescolib.org
  4. github.com
  5. android.com
  6. methodscount.com
  7. choosealicense.com
  8. facebook.com

https://www.bignerdranch.com/blog/solving-the-android-image-loading-problem-an-updated-guide/