Android Glide Library Example

On loading the list of images manually these three problems encounter i.e OutOfMemoryError, slow loading and UI unresponsiveness(flickering). To come out from these problems we can use Glide library. In this article, we will talk about Glide in brief, how glide solved the above problems and also build a simple image gallery app where all the images will be loaded from internet and displayed in a grid manner.

Introduction to Glide Library

Glide is an open source image loading and caching library for Android APPs developed by bumptech. It is fast, efficient and widely used image loading library, primarily focused on smooth scrolling. It is used in many popular Android Apps and one of the most popular library for image loading and caching.

To load the image in an imageView using glide we have to simply write the below line:

Glide.with(mContext)
.load(imgUrl)  
.into(imageView);

Glide library solves the above discuss problems that come while loading a list of images manually :

OutOfMemoryError

Glide mainly takes these three as parameter i.e context/fragment/Activity, imageUrl/drawable image and imageView. In order to solve the OutOfMemoryError problem, it takes imageView. Let’s say your server is sending an image of (2000×2000) but in your android application, you are going to show an image of (200×200). When you decode server image in memory it will take around 40mb.

Glide has taken the imageView as a parameter so it knows the actual height and width of the imageView in which you want to show the image. It knows that it is (200×200). So Glide instead of loading the full-size image(2000×2000) from the given URL into the disk cache it will first resize it to the size of the imageView(200×200) and then store it into the disk cache after that it will decode the resized image(200×200) into bitmap and load it into the memory so its size will become 4mb. In this way, it helps to prevent your app from throwing popular OutOfMemoryError.

Fast Loading and UI responsive

Just like other systems do Glide will also cancel all the network call and only make network calls that are visible to user. For example, you are scrolling list of images and you stop at 26th item, so the network call will only be going for the 26 and above item that is visible.

One more important thing that glide do internally is caching. When we scroll the list of images from bottom to top it will not download the image again instead it will check the image in memory cache if it exists then it will get it and display it to the user. But in case if it does not exist then it will check in disk cache if it is there then it will get the file image from the file system and decode it to bitmap, store it to memory cache and return it to imageView. In case if the image is not available in disk cache also then only it will make a network call , store it in both memory and disk cache, get the image and display it.

Screenshot 2019-09-14 16.10.21

Advantages of using Glide library :

  • Supports fetching, decoding, and displaying video stills, images, and animated GIFs.
  • It is designed to work with Activity and Fragment’s life cycle too. You can pass the activity or fragment context with Glide.with() and it will brilliantly integrate with activity lifecycle callbacks such as onPause() or onResume().
  • Glide supports animated GIF images and because of Glide integrates with your activity life-cycle, animated GIFs are also paused in onStop() to avoid draining the battery in the background.
  • Loads thumbnail (blurred) first and then loads the high-resolution image like in WhatsApp or Facebook
  • Glide has its own implementation of HttpURLConnection which loads images from remote URLs over the network.
  • One good thing about Glide is, it provides various configuration and customization options. So, you can tweak Glide library as per your requirement. You can read more about this at configuration page.
  • You can also add placeholder image to display while loading the image or while the image loading fails.
  • Supports Crossfading effects between the media
  • Supports image arbitrary transformations like loading image in circular shape or any other shape.
  • Provides better Memory and disk caching mechanisms.

How to Use It?

Integrating Glide in your project is very easy. First, add the glide dependency to your build.gradle.

build.gradle

dependencies {
    
    //glide
    implementation 'com.github.bumptech.glide:glide:4.9.0'
   
}

Second load the image into ImageView using below code snippet.

String imgUrl = "https://www.gettyimages.ca/gi-resources/images/Homepage/Hero/UK/CMS_Creative_164657191_Kingfisher.jpg";

ImageView imageView = (ImageView) view.findViewById(R.id.thumbnail);

Glide.with(mContext).load(imgUrl)
.thumbnail(0.5f)
.crossFade()
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(imageView);

Now let’s start building the image gallery app.

Building Image Gallery App

1. Create a new project in Android Studio from File ⇒ New Project. Select Blank Activity and then name the application as GlideDemo.

2. Open build.gradle and add Glide and RecyclerView dependencies.  RecyclerView is used to show the gallery images in a Grid fashion.

Add Dependencies Into build.gradle

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'androidx.appcompat:appcompat:1.0.2'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test:runner:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'

    //glide
    implementation 'com.github.bumptech.glide:glide:4.9.0'

    // recyclerView
    implementation 'androidx.recyclerview:recyclerview-selection:1.0.0'

}

3 .Open AndroidManifest.xml and add the INTERNET permission as we need to get the image from Url.

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="trendlife.glidedemo">

    <uses-permission android:name="android.permission.INTERNET"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

4 .Open the layout file of your MainActivity and add the recyclerView as shown below:

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/colorPrimaryDark"
    tools:context=".MainActivity">


    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerview"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:scrollbars="vertical"
       />

</RelativeLayout>

5 .Under res ⇒ layout, create a layout named gallery_thumbnail.xml. This layout contains an ImageView to display the thumbnail image in the gallery view.

gallery_thumbnail.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="200dp"
    android:layout_height="200dp"
    android:orientation="vertical">

    <ImageView
        android:id="@+id/thumbnail"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="fitXY" />

</LinearLayout>

6 .Create a new model class imageUrl.java. These URLs will be invoked by the Glide library on bind to display the images one by one in the image gallery.

imageUrl.java

package trendlife.glidedemo;

public class ImageUrl {


    String imageUrl;

    public String getImageUrl() {
        return imageUrl;
    }

    public void setImageUrl(String imageUrl) {
        this.imageUrl = imageUrl;
    }
}

7 .Under the root project directory, create a class named GalleryAdapter.java This is an adapter class which inflates the gallery_thumbnail.xml and renders the images in recyclerView.

GalleryAdapter.java

package trendlife.glidedemo;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;

import com.bumptech.glide.Glide;
import com.bumptech.glide.Priority;
import com.bumptech.glide.request.RequestOptions;

import java.util.ArrayList;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

public class GalleryAdapter extends RecyclerView.Adapter<GalleryAdapter.MyViewHolder> {

    private ArrayList<ImageUrl> imageUrls;
    private Context context;

    public GalleryAdapter(Context context, ArrayList<ImageUrl> imageUrls) {
        this.context = context;
        this.imageUrls = imageUrls;
    }

    @NonNull
    @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.gallery_thumbnail, parent, false);
        return new MyViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
        
       RequestOptions requestOptions = new RequestOptions()
                .placeholder(R.drawable.place_holder_image)
                .error(R.drawable.error_img)
                .fitCenter();

        Glide.with(context)
                .setDefaultRequestOptions(requestOptions)
                .load(imageUrls.get(position).getImageUrl())
                .into(holder.img);

    }

    class MyViewHolder extends RecyclerView.ViewHolder {

        ImageView img;

        public MyViewHolder(@NonNull View itemView) {
            super(itemView);
            img = itemView.findViewById(R.id.thumbnail);
        }
    }

    @Override
    public int getItemCount() {
        return imageUrls.size();
    }
}

8 .Finally, open MainActivity.java and pass the array list to recyclerView’s adapter class as shown below:

MainActivity.java

package trendlife.glidedemo;

import android.os.Bundle;
import android.util.Log;

import java.util.ArrayList;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

public class MainActivity extends AppCompatActivity {

    RecyclerView recyclerView;
    GalleryAdapter mAdapter;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        recyclerView = findViewById(R.id.recyclerview);


        RecyclerView.LayoutManager layoutManager = new GridLayoutManager(getApplicationContext(), 2);
        ArrayList imageUrlList = prepareData();
        mAdapter = new GalleryAdapter(getApplicationContext(), imageUrlList);


        recyclerView.setLayoutManager(layoutManager);
        recyclerView.setItemAnimator(new DefaultItemAnimator());
        recyclerView.setAdapter(mAdapter);


    }

    private ArrayList prepareData() {

// here you should give your image URLs and that can be a link from the Internet
        String imageUrls[] = {
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQWqxdGGltL3Ap_6e6j5L8Ga9Ly08VRSsIyGBPzkdMdCrSuDOomTA",
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ8lzDnZhrCxA6xeFtoRno_VC2kmU5G5MCdLjscFT9EXcW9fRp1JA",
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQ0Frq15F4tqShs3o8_EOQWmRDnBpvqze2-Ivnh7_hPcpFA_nxJtA",
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT1PLkjujhPe8bFhY_C3eVTk3YZKV7D_FvgmMdzRpU10f8cg2Xq",
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcR-BshanQe-72-_aILEOrdy0tktLS3D0OyCuZETTHS-xspWyyTdgQ",
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTIog4jVdAtTmktR6ZWeOLWSOuciGhIpnYcd_ZaeG9fEFAoOKZsDw",
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT2RiBylPwwMIa9Ky0eyss19pxrtKBcgiZGgY70G0YfbUXSqT1qNw",
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQSpSvHExAZQVYjGSNFaG4aMoow4IIHXHDmVftcTnYf0ICaXtegPg"
}; 

ArrayList imageUrlList = new ArrayList<>(); 
for (int i = 0; i < imageUrls.length; i++) {
 ImageUrl imageUrl = new ImageUrl(); 
imageUrl.setImageUrl(imageUrls[i]); 
imageUrlList.add(imageUrl); } 
Log.d("MainActivity", "List count: " + imageUrlList.size()); 
return imageUrlList; } 
}

If you run the app, you can see the images displayed in a grid manner. Be sure that your device is connected to the internet.

Screenshot_1568731358

 

 

 

 

Leave a Reply