Headertab

Drop Down MenusCSS Drop Down MenuPure CSS Dropdown Menu

Saturday, 13 August 2016

Glide Image loader Library in android


Hello friends,

In this article explains how to build a simple image in app where the image will be loaded from internet. Glide is new image loading library and not only one lib the many other lib use the image loading like Picasso.

What is Picasso ?

Picasso is an image library for Android. It's created and maintained by Square, and caters to image loading and processing. It simplifies the process of displaying images from external locations. In many cases only a few lines of code is required to implement this neat library.

Picasso shines for displaying remote images. The library handles every stage of the process, from the initial HTTP request to the caching of the image. This can be quite verbose when writing code to perform these actions yourself. In this quick tip, we look at a few common use cases.

Picasso features :

1> Thumbnail support
2> Lifecycle integration
3> Transcoding
4> OkHttp Support
5> Volley Support


Why use glide:

You might be thinking that why we should use a 3rd party library. You can achieve your task without using a 3rd party API as well. I have also posted a tutorial about downloading image without using 3rd party library. But if you will use the core method then it would take larger amount of code. But if we will use a 3rd party library like picasso then we will achieve our goal in few lines of code.  So if we will not use a 3rd party library then  we would need

1> Very large amount of code to be written
2> We have to write another logic to implement caching. Caching is very important to make the application faster.
3> We also have to deal with memory while writing the code.
BUT if we will use picasso then all the above mentioned things would be taken care of by picasso.


What is Glide?

Glide is an open source media management framework for Android that wraps media decoding, memory and disk caching, and resource pooling into a simple and easy to use interface. Glide supports fetching, decoding, and displaying video stills, images, and animated GIFs. Glide includes a flexible API that allows developers to plug in to almost any network stack.

Glide’s primary focus is on making scrolling any kind of a list of images as smooth and fast as possible, but Glide is also effective for almost any case where you need to fetch, resize, and display a remote image.


Glide features :

1> Animated GIF decoding
2> Local video stills
3> Thumbnail support
4> Lifecycle integration
5> Transcoding
6> Animations
7> OkHttp Support
8> Volley Support

Why use glide:

It simplifies the process of loading images from external urls and display on your application. For example, downloading an image from server, is one of the most common task in any application. And it needs quite a larger amount of code to achieve this via android networking API’s. By using Glide, you can achieve this with few lines of code.

                                                                  It is always not about downloading image from remote location. You also have to think of implementing image caching logic in order to provide a seamless user experience. Glide provides automatic image caching.

                                                                  Image transformation is a costly affair. If your application need deal with such runtime image transformation, you must be watchful about OutOfMemoryException. Glide deals with it, so you dont have to do it yourself.


How to use?

Before you can use it in your projects you need to add the following compile line to your Gradle dependencies block in your build.gradle file.


dependencies {
    compile 'com.github.bumptech.glide:glide:3.6.1'
    compile 'com.android.support:support-v4:19.1.0'
  }

MainActvity.java

import android.content.Context;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;

import com.bumptech.glide.Glide;
import com.bumptech.glide.GlideBuilder;
import com.bumptech.glide.load.DecodeFormat;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.load.engine.cache.InternalCacheDiskCacheFactory;
import com.bumptech.glide.module.GlideModule;
import com.samset.user.volleyexample.R;

public class MainActivity extends AppCompatActivity {

    private ImageView imageView;
    String imgUrl = "http://yourapiurl/sample.jpg";

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

        imageView = (ImageView) findViewById(R.id.img);
        Glide.with(this).load(imgUrl)
                .thumbnail(0.5f)
                .crossFade()
                .diskCacheStrategy(DiskCacheStrategy.ALL)
                .into(imageView);

//You can set manually DecodeFormat.PREFER_ARGB_8888 by default set RGB565
  /*Glide.with(this).load(imgUrl).asBitmap().format(DecodeFormat.PREFER_ARGB_8888)
                .thumbnail(0.5f)
                .diskCacheStrategy(DiskCacheStrategy.ALL)
                .into(imageView);*/
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

    }
}


activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<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"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".activities.MainActivity">

    <TextView
        android:id="@+id/tv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:gravity="center"
        android:text="Welcome to glide tutorial" />
    <ImageView
        android:layout_marginTop="10dp"
        android:id="@+id/img"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>


Also use methods

     Loading Images from server

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

  //Loading image from below url into imageView
        Glide.with(this).load("IMAGE URL HERE").into(imageView);


    Set Images placeholder

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


      Glide.with(this)
        .load("IMAGE URL HERE")
        .placeholder(R.drawable.placeholder)
        .into(imageView);


    Set Images error

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

  Glide.with(this)
        .load("IMAGE URL HERE")
        .placeholder(R.drawable.placeholder)
        .error(R.drawable.imagenotfound)
        .into(imageView);

    Image Resizing and Cropping

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

  Glide.with(this)
        .load("IMAGE URL HERE")
        .placeholder(R.drawable.placeholder)
        .error(R.drawable.imagenotfound)
        .into(imageView);


If you develop very large app and use max images then you face MemoryOutOfBound exception then you can customise as your need cache memory.

Cache

We're customizing Glide, we'll need to create a new Glide module. As you've seen in the previous blog post, the applyOptions method gives us access to the GlideBuilder object. The GlideBuilder offers us several methods to customize Glide's caching. First, let's look at the memory cache.

The memory cache keeps the images in the device's RAM. There is no IO action going on and thus it's very fast. The flip side is that the size of the RAM is quite limited. Finding the right balance of keeping a large memory cache (space for many images) versus a small memory cache (minimize our app's hunger for resources) is not easy. Glide internally uses the MemorySizeCalculator class to determine the size of the memory cache and the bitmap pool. The bitmap pool keeps the images allocated in your app's heap. The correct size of the bitmap pool is essential as well, since it avoids too many re-allocations of images and thus makes the garbage collector's life easier.

Luckily, you've access to Glide's MemorySizeCalculator class and the default calculation:



MemorySizeCalculator calculator = new MemorySizeCalculator(context);  
int defaultMemoryCacheSize = calculator.getMemoryCacheSize();  
int defaultBitmapPoolSize = calculator.getBitmapPoolSize();  

The code above is useful if we want to use the default values as baseline and adjust it from there. For example, if you think your app needs 20% larger caches than Glide's default values, calculate them using our variables above:

int customMemoryCacheSize = (int) (1.2 * defaultMemoryCacheSize);  
int customBitmapPoolSize = (int) (1.2 * defaultBitmapPoolSize); 


Since we've figured out our memory cache and bitmap pool sizes, we can finally get to code our Glide module. In the applyOptions() method, we can call the appropriate methods on the GlideBuilder object:


public class CustomCachingGlideModule implements GlideModule {  
    @Override public void applyOptions(Context context, GlideBuilder builder) {
        MemorySizeCalculator calculator = new MemorySizeCalculator(context);
        int defaultMemoryCacheSize = calculator.getMemoryCacheSize();
        int defaultBitmapPoolSize = calculator.getBitmapPoolSize();

        int customMemoryCacheSize = (int) (1.2 * defaultMemoryCacheSize);
        int customBitmapPoolSize = (int) (1.2 * defaultBitmapPoolSize);

        builder.setMemoryCache( new LruResourceCache( customMemoryCacheSize );
        builder.setBitmapPool( new LruBitmapPool( customBitmapPoolSize );
    }

    @Override public void registerComponents(Context context, Glide glide) {
        // nothing to do here
    }
}

As you can see from the last two lines in the applyOptions() method, we can't set the size directly. We're creating an instance of the LruResourceCache and the LruBitmapPool class. Both are the default implementations of Glide. Thus, if you only want to adjust the size, you can just continue to use them by just passing a different size value to the constructor.

Customize Disk Cache

Adjusting the size of the disk cache works very similar, but we've one decision more to make. The disk cache can be located in the apps private directory (in other words, no app has access to it, except your own). Otherwise, the disk cache can also be located on the external, public directory (for more information, see Storage Options. A combination of both locations is not possible with the default settings. Glide offers an implementation for either one of the two options with the InternalCacheDiskCacheFactory and ExternalCacheDiskCacheFactory. Just like the memory cache constructor, both disk cache factories accept a size value in their constructor:


public class CustomCachingGlideModule implements GlideModule {  
    @Override
    public void applyOptions(Context context, GlideBuilder builder) {
        // set size & external vs. internal
        int cacheSize100MegaBytes = 104857600;

        builder.setDiskCache(
            new InternalCacheDiskCacheFactory(context, cacheSize100MegaBytes)
        );

        //builder.setDiskCache(
        //new ExternalCacheDiskCacheFactory(context, cacheSize100MegaBytes));
    }

    @Override
    public void registerComponents(Context context, Glide glide) {
        // nothing to do here
    }
}

The code above would set the disk cache to the app's internal directory and also set the maximum size to 100 megabytes. The line, which is behind the comment slashes, would set the disk cache to the external directory (and also set the maximum size to 100 megabytes).

Both options you've seen above don't let you choose a specific directory. If you require to move the disk cache to some specific location, you can utilize the DiskLruCacheFactory:


// or any other path
String downloadDirectoryPath = Environment.getDownloadCacheDirectory().getPath(); 

builder.setDiskCache(  
        new DiskLruCacheFactory( downloadDirectoryPath, cacheSize100MegaBytes )
);

// In case you want to specify a cache sub folder (i.e. "glidecache"):
//builder.setDiskCache(
//    new DiskLruCacheFactory( downloadDirectoryPath, "glidecache", cacheSize100MegaBytes ) 
//);


Use the upper option to set a directory directly. The bottom option would create and use a directory inside your passed directory path. As always, the last parameter is the size of the cache in bytes.



CompleteCode

      MainActivity.java


import android.content.Context;
import android.content.Intent;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;

import com.bumptech.glide.Glide;
import com.bumptech.glide.GlideBuilder;
import com.bumptech.glide.load.DecodeFormat;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.load.engine.cache.DiskLruCacheFactory;
import com.bumptech.glide.load.engine.cache.ExternalCacheDiskCacheFactory;
import com.bumptech.glide.load.engine.cache.InternalCacheDiskCacheFactory;
import com.bumptech.glide.module.GlideModule;
import com.samset.user.volleyexample.R;

public class MainActivity extends AppCompatActivity implements GlideModule {

    private ImageView imageView;
    String imgUrl = "http://yourapiurl/sample.jpg";

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

        imageView = (ImageView) findViewById(R.id.img);
        Glide.with(this).load(imgUrl)
                .thumbnail(0.5f)
                .crossFade()
                .diskCacheStrategy(DiskCacheStrategy.ALL)
                .into(imageView);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

    }

    @Override
    public void applyOptions(Context context, GlideBuilder builder) {
        // add this code your picture quality good
        builder.setDecodeFormat(DecodeFormat.ALWAYS_ARGB_8888);



        int cacheSize100MegaBytes = 104857600;
        // This is maintain diskcache internal memory
        builder.setDiskCache(new InternalCacheDiskCacheFactory(context, cacheSize100MegaBytes));
        // This is maintain diskcache external memory
        builder.setDiskCache(new ExternalCacheDiskCacheFactory(context, cacheSize100MegaBytes));

        //If you require to move the disk cache to some specific location, you can utilize the DiskLruCacheFactory:
        String downloadDirectoryPath = Environment.getDownloadCacheDirectory().getPath();
        builder.setDiskCache(new DiskLruCacheFactory( downloadDirectoryPath, cacheSize100MegaBytes ));

    }

    @Override
    public void registerComponents(Context context, Glide glide) {
       // glide.register(Model.class, Data.class, new MyModelLoader());
    }
}


AndroidMainifest.xml


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

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

    <application
   
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
         <meta-data android:name="com.inthecheesefactory.lab.glidepicasso.GlideConfiguration"
            android:value="GlideModule"/>

        <activity android:name=".activities.MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

</manifest>

Thank you