Skip to content

Commit

Permalink
Create glide okhttp integration using okhttp4 dependency
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 496520960
  • Loading branch information
sjudd authored and glide-copybara-robot committed Dec 20, 2022
1 parent 128d290 commit 464002b
Show file tree
Hide file tree
Showing 9 changed files with 257 additions and 0 deletions.
2 changes: 2 additions & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ VERSION_NAME=4.15.0-SNAPSHOT
## SDK versioning
COMPILE_SDK_VERSION=33
MIN_SDK_VERSION=14
OK_HTTP_4_MIN_SDK_VERSION=21
TARGET_SDK_VERSION=32

## AndroidX versions
Expand Down Expand Up @@ -105,6 +106,7 @@ MOCKITO_ANDROID_VERSION=2.24.0
MOCKITO_VERSION=2.24.0
MOCKWEBSERVER_VERSION=3.0.0-RC1
OK_HTTP_VERSION=3.10.0
OK_HTTP_4_VERSION=4.10.0
PMD_VERSION=6.0.0
ROBOLECTRIC_VERSION=4.8.1
TRUTH_VERSION=1.1.3
Expand Down
27 changes: 27 additions & 0 deletions integration/okhttp4/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
apply plugin: 'com.android.library'

dependencies {
implementation project(':library')
annotationProcessor project(':annotation:compiler')

api "com.squareup.okhttp3:okhttp:${OK_HTTP_4_VERSION}"
api "androidx.annotation:annotation:${ANDROID_X_ANNOTATION_VERSION}"
}

android {
compileSdk COMPILE_SDK_VERSION as int

defaultConfig {
minSdk OK_HTTP_4_MIN_SDK_VERSION as int
targetSdk TARGET_SDK_VERSION as int

versionName VERSION_NAME as String
}

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}

apply from: "${rootProject.projectDir}/scripts/upload.gradle"
4 changes: 4 additions & 0 deletions integration/okhttp4/gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
POM_NAME=Glide OkHttp 4.x Integration
POM_ARTIFACT_ID=okhttp4-integration
POM_PACKAGING=aar
POM_DESCRIPTION=An integration library to use OkHttp 4.x to fetch data over http/https in Glide
5 changes: 5 additions & 0 deletions integration/okhttp4/lint.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<lint>
<issue id="AllowBackup" severity="ignore"/>
</issue>
</lint>
5 changes: 5 additions & 0 deletions integration/okhttp4/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<manifest
package="com.bumptech.glide.integration.okhttp">

<application />
</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.bumptech.glide.integration.okhttp3;

import android.content.Context;
import androidx.annotation.NonNull;
import com.bumptech.glide.Glide;
import com.bumptech.glide.Registry;
import com.bumptech.glide.annotation.GlideModule;
import com.bumptech.glide.load.model.GlideUrl;
import com.bumptech.glide.module.AppGlideModule;
import com.bumptech.glide.module.LibraryGlideModule;
import java.io.InputStream;

/**
* Registers OkHttp related classes via Glide's annotation processor.
*
* <p>For Applications that depend on this library and include an {@link AppGlideModule} and Glide's
* annotation processor, this class will be automatically included.
*/
@GlideModule
public final class OkHttpLibraryGlideModule extends LibraryGlideModule {
@Override
public void registerComponents(
@NonNull Context context, @NonNull Glide glide, @NonNull Registry registry) {
registry.replace(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
package com.bumptech.glide.integration.okhttp3;

import android.util.Log;
import androidx.annotation.NonNull;
import com.bumptech.glide.Priority;
import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.HttpException;
import com.bumptech.glide.load.data.DataFetcher;
import com.bumptech.glide.load.model.GlideUrl;
import com.bumptech.glide.util.ContentLengthInputStream;
import com.bumptech.glide.util.Preconditions;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import okhttp3.Call;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;

/** Fetches an {@link InputStream} using the okhttp library. */
public class OkHttpStreamFetcher implements DataFetcher<InputStream>, okhttp3.Callback {
private static final String TAG = "OkHttpFetcher";
private final Call.Factory client;
private final GlideUrl url;
private InputStream stream;
private ResponseBody responseBody;
private DataCallback<? super InputStream> callback;
// call may be accessed on the main thread while the object is in use on other threads. All other
// accesses to variables may occur on different threads, but only one at a time.
private volatile Call call;

// Public API.
@SuppressWarnings("WeakerAccess")
public OkHttpStreamFetcher(Call.Factory client, GlideUrl url) {
this.client = client;
this.url = url;
}

@Override
public void loadData(
@NonNull Priority priority, @NonNull final DataCallback<? super InputStream> callback) {
Request.Builder requestBuilder = new Request.Builder().url(url.toStringUrl());
for (Map.Entry<String, String> headerEntry : url.getHeaders().entrySet()) {
String key = headerEntry.getKey();
requestBuilder.addHeader(key, headerEntry.getValue());
}
Request request = requestBuilder.build();
this.callback = callback;

call = client.newCall(request);
call.enqueue(this);
}

@Override
public void onFailure(@NonNull Call call, @NonNull IOException e) {
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "OkHttp failed to obtain result", e);
}

callback.onLoadFailed(e);
}

@Override
public void onResponse(@NonNull Call call, @NonNull Response response) {
responseBody = response.body();
if (response.isSuccessful()) {
long contentLength = Preconditions.checkNotNull(responseBody).contentLength();
stream = ContentLengthInputStream.obtain(responseBody.byteStream(), contentLength);
callback.onDataReady(stream);
} else {
callback.onLoadFailed(new HttpException(response.message(), response.code()));
}
}

@Override
public void cleanup() {
try {
if (stream != null) {
stream.close();
}
} catch (IOException e) {
// Ignored
}
if (responseBody != null) {
responseBody.close();
}
callback = null;
}

@Override
public void cancel() {
Call local = call;
if (local != null) {
local.cancel();
}
}

@NonNull
@Override
public Class<InputStream> getDataClass() {
return InputStream.class;
}

@NonNull
@Override
public DataSource getDataSource() {
return DataSource.REMOTE;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package com.bumptech.glide.integration.okhttp3;

import androidx.annotation.NonNull;
import com.bumptech.glide.load.Options;
import com.bumptech.glide.load.model.GlideUrl;
import com.bumptech.glide.load.model.ModelLoader;
import com.bumptech.glide.load.model.ModelLoaderFactory;
import com.bumptech.glide.load.model.MultiModelLoaderFactory;
import java.io.InputStream;
import okhttp3.Call;
import okhttp3.OkHttpClient;

/** A simple model loader for fetching media over http/https using OkHttp. */
public class OkHttpUrlLoader implements ModelLoader<GlideUrl, InputStream> {

private final Call.Factory client;

// Public API.
@SuppressWarnings("WeakerAccess")
public OkHttpUrlLoader(@NonNull Call.Factory client) {
this.client = client;
}

@Override
public boolean handles(@NonNull GlideUrl url) {
return true;
}

@Override
public LoadData<InputStream> buildLoadData(
@NonNull GlideUrl model, int width, int height, @NonNull Options options) {
return new LoadData<>(model, new OkHttpStreamFetcher(client, model));
}

/** The default factory for {@link OkHttpUrlLoader}s. */
// Public API.
@SuppressWarnings("WeakerAccess")
public static class Factory implements ModelLoaderFactory<GlideUrl, InputStream> {
private static volatile Call.Factory internalClient;
private final Call.Factory client;

private static Call.Factory getInternalClient() {
if (internalClient == null) {
synchronized (Factory.class) {
if (internalClient == null) {
internalClient = new OkHttpClient();
}
}
}
return internalClient;
}

/** Constructor for a new Factory that runs requests using a static singleton client. */
public Factory() {
this(getInternalClient());
}

/**
* Constructor for a new Factory that runs requests using given client.
*
* @param client this is typically an instance of {@code OkHttpClient}.
*/
public Factory(@NonNull Call.Factory client) {
this.client = client;
}

@NonNull
@Override
public ModelLoader<GlideUrl, InputStream> build(MultiModelLoaderFactory multiFactory) {
return new OkHttpUrlLoader(client);
}

@Override
public void teardown() {
// Do nothing, this instance doesn't own the client.
}
}
}
1 change: 1 addition & 0 deletions settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ include ':integration:gifencoder'
include ':integration:ktx'
include ':integration:okhttp'
include ':integration:okhttp3'
include ':integration:okhttp4'
include ':integration:recyclerview'
include ':integration:volley'
include ':testutil'
Expand Down

0 comments on commit 464002b

Please sign in to comment.