Skip to content

Instantly share code, notes, and snippets.

@fbis251
Created September 21, 2015 15:28
Show Gist options
  • Star 18 You must be signed in to star a gist
  • Fork 7 You must be signed in to fork a gist
  • Save fbis251/cfa169fd9e1e142e042c to your computer and use it in GitHub Desktop.
Save fbis251/cfa169fd9e1e142e042c to your computer and use it in GitHub Desktop.
Android Glide + okhttp progress example
package com.example.glidetest.app;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.ImageView;
import android.widget.ProgressBar;
import com.bumptech.glide.Glide;
import com.bumptech.glide.integration.okhttp.OkHttpUrlLoader;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.load.model.GlideUrl;
import com.squareup.okhttp.Interceptor;
import com.squareup.okhttp.MediaType;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Response;
import com.squareup.okhttp.ResponseBody;
import java.io.IOException;
import java.io.InputStream;
import okio.Buffer;
import okio.BufferedSource;
import okio.ForwardingSource;
import okio.Okio;
import okio.Source;
/*
For more information see:
https://github.com/square/okhttp/blob/master/samples/guide/src/main/java/com/squareup/okhttp/recipes/Progress.java
*/
public class MainActivity extends AppCompatActivity {
private static final String LOG_TAG = "MainActivity";
private final static String DOWNLOAD_URL = "https://i.imgur.com/mYBXl6X.jpg";
private OkHttpClient mOkHttpClient;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ImageView imageView = (ImageView) findViewById(R.id.image_view);
final ProgressBar progressBar = (ProgressBar) findViewById(R.id.progressBar);
mOkHttpClient = new OkHttpClient();
final ProgressListener progressListener = new ProgressListener() {
@Override
public void update(long bytesRead, long contentLength, boolean done) {
int progress = (int) ((100 * bytesRead) / contentLength);
// Enable if you want to see the progress with logcat
// Log.v(LOG_TAG, "Progress: " + progress + "%");
progressBar.setProgress(progress);
if (done) {
Log.i(LOG_TAG, "Done loading");
}
}
};
mOkHttpClient.networkInterceptors().add(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Response originalResponse = chain.proceed(chain.request());
return originalResponse.newBuilder()
.body(new ProgressResponseBody(originalResponse.body(), progressListener))
.build();
}
});
Glide.get(this)
.register(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory(mOkHttpClient));
Glide.with(this)
.load(DOWNLOAD_URL)
// Disabling cache to see download progress with every app load
// You may want to enable caching again in production
.diskCacheStrategy(DiskCacheStrategy.NONE)
.into(imageView);
}
private static class ProgressResponseBody extends ResponseBody {
private final ResponseBody responseBody;
private final ProgressListener progressListener;
private BufferedSource bufferedSource;
public ProgressResponseBody(ResponseBody responseBody, ProgressListener progressListener) {
this.responseBody = responseBody;
this.progressListener = progressListener;
}
@Override
public MediaType contentType() {
return responseBody.contentType();
}
@Override
public long contentLength() throws IOException {
return responseBody.contentLength();
}
@Override
public BufferedSource source() throws IOException {
if (bufferedSource == null) {
bufferedSource = Okio.buffer(source(responseBody.source()));
}
return bufferedSource;
}
private Source source(Source source) {
return new ForwardingSource(source) {
long totalBytesRead = 0L;
@Override
public long read(Buffer sink, long byteCount) throws IOException {
long bytesRead = super.read(sink, byteCount);
// read() returns the number of bytes read, or -1 if this source is exhausted.
totalBytesRead += bytesRead != -1 ? bytesRead : 0;
progressListener.update(totalBytesRead, responseBody.contentLength(), bytesRead == -1);
return bytesRead;
}
};
}
}
interface ProgressListener {
void update(long bytesRead, long contentLength, boolean done);
}
}
@TWiStErRob
Copy link

This good if you have one activity and one image, but it won't work with multiple images and also leaks the activity if you don't re-register the default loader factor after the image is loaded or the user leaves the activity.

The idea is good though, it would be nice to see if the image loading is slow because the network is slow, or because Glide is munching too much on it.

@kalyaganov
Copy link

Hi, this is great solution, but how can i reregister OkHttpUrlLoader back?

@TWiStErRob
Copy link

@futurobot Default constructor of OkHttpUrlLoader.Factory uses a singleton client, see sources:

Glide.get(this).register(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory(mOkHttpClient));
Glide
    .with(this)
    .load(DOWNLOAD_URL)
    .listener(new RequestListener<String, GlideDrawable>() {
        @Override public boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource) {
            Glide.get(MainActivity.this).register(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory());
            return false;
        }
        @Override public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
            Glide.get(MainActivity.this).register(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory());
            return false;
        }
    })
    .into(imageView)
;

@afaideen
Copy link

afaideen commented Jan 14, 2017

i put a text view to display value of progress like this, But it fails! Reply me afaideen@gmail.com.

final ProgressListener progressListener = new ProgressListener() {
@OverRide
public void update(long bytesRead, long contentLength, boolean done) {
int progress = (int) ((100 * bytesRead) / contentLength);

            // Enable if you want to see the progress with logcat
            // Log.v(LOG_TAG, "Progress: " + progress + "%");
            progressBar.setProgress(progress);
            textviewPercent.setText(progress);
            if (done) {
                Log.i("GifActivity", "Done loading");
            }
        }

    };

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment