[Android / Glide] GlideApp 생성절차

아래 방식은 4.x.x 버전에서 유효하다. 3.x.x 버전의 Glide에서는 Manifest.xml에 meta-data를 추가하는 방식으로 진행된다.
참고) 3.x.x는 아래 링크가 더 도움이 될 것 같다. 3.x.x에서는 AppGlideModule이 아닌 GlideModule을 상속받는 클래스를 만들어야 한다.
https://medium.com/@PaulinaSadowska/adding-headers-to-image-request-in-glide-dc9640ca9b12

1. app/build.gradle에 dependencies 추가

1
2
3
4
5
6
7
8
9
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
...
dependencies {
...
    implementation 'com.github.bumptech.glide:glide:4.11.0'
    implementation "com.github.bumptech.glide:okhttp3-integration:4.11.0"
    kapt 'com.github.bumptech.glide:compiler:4.11.0'
}

코틀린을 쓰고 있다면, glide:compiler dependencies를 kapt로 추가해줘야한다.
이를 위해 선행작업으로 gradle.build의 최상단에 kotlin-kapt 도 필요하다.

  • glide:glide는 기본적으로 Glide 라이브러리를 사용하기 위해 추가됨.
  • okhttp3-integration는 CustomGlideModule에서 사용하기 위함.
  • glide:compiler는 GeneratedAppGlideModuleImpl를 생성하기 위함.
    이후 proguard-rules.pro에서 GeneratedAppGlideModuleImpl를 keep 해주는데 이는 GlideApp을 사용하기 위해 CustomGlideModule과 같은 패키지(net.common.utils.GlideApp)에 만들어진다.(4번 절차 참조)

2. UserAgentInterceptor 생성

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import java.io.IOException;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;

public class UserAgentInterceptor implements Interceptor {

private Context mContext;
public UserAgentInterceptor(Context context) {
mContext = context;
}

@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request()
.newBuilder()
.header("User-Agent", getUserAgent(mContext))
.build();
return chain.proceed(request);
}
}

3. CustomGlideModule 생성

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package net.common.utils;

import com.bumptech.glide.Glide;
import com.bumptech.glide.GlideBuilder;
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.integration.okhttp3.OkHttpUrlLoader.Factory;
import java.io.InputStream;
import okhttp3.OkHttpClient;

@GlideModule
public final class CustomGlideModule extends AppGlideModule {

@Override
public void applyOptions(@NonNull Context context,
    @NonNull GlideBuilder builder) {
// 아무 것도 수정하지 않지만 오버라이드 해줘야함
super.applyOptions(context, builder);
}

@Override
public void registerComponents(@NonNull Context context,
    @NonNull Glide glide, @NonNull Registry registry) {
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(new UserAgentInterceptor(context))
.build();
registry.replace(GlideUrl.class, InputStream.class, new Factory(client));
}
}
  • @GlideModule 어노테이션 선언 꼭 잊지 말 것.
  • 3.x.x와는 다르게 AppGlideModule을 상속받아 커스텀 클래스를 만들어준다.
  • registerComponents에서 OkHttpClient를 통해 커스텀 인터셉터를 추가해준다.

AppGlideModule과 LibraryGlideModule

AppGlideModule(을 상속받은 CustomAppGM)은 애플리케이션 단에, LibraryGlideModule(을 상속받은 ~ 생략)은 공통 라이브러리 단에 구현하면 된다.

이때 GlideModule을 커스텀할 경우, CustomAppGM의 구현은 필수적이나 CustomLibraryGM의 구현은 선택적이어서, CustomLibraryGM만 구현해선 안 된다.

그리고 공통 라이브러리에 정의한 모든 CustomLibraryGM은 CustomAppGM에서 통합적으로 추가된다.

4. 재빌드

3번까지 진행 후 재빌드(Build>Make Project) 하자.

  • app/build/generated/source/kapt/appDebug/com.bumptech.glide.GeneratedAppGlideModuleImpl
  • app/build/generated/source/kapt/appDebug/net.common.utils.GlideApp

위와 같은 로케이션에 GeneratedAppGlideModuleImplGlideApp이 생성되는 것을 확인할 수 있다. 이렇게 되면 이제 GlideApp을 사용할 준비가 된 것.

  • GlideApp은 CustomGlideModule을 정의한 패키지 내에 만들어진다.

  • 위의 두 파일이 만약 생성되지 않는다면

    • build.gradle의 kapt를 확인할 것
    • @GlideModule 어노테이션 넣었는지 확인할 것

5. app/proguard-rules.pro 편집

1
2
-keep public class * extends com.bumptech.glide.module.AppGlideModule
-keep class com.bumptech.glide.GeneratedAppGlideModuleImpl

위와 같은 keep을 추가해줘야한다.

첫번째 라인(* extends AppGlideModule)은 CustomAppGlideModule을 위해서 쓰임.

두번째 라인(GeneratedAppGlideModuleImpl)은 빨간줄로 오류표시가 날 수 있는데, 4번에서 말한 것처럼 kapt로 추가된 의존성에 의해 빌드 후 생성되는 파일이라서이다. 빌드 후 generated에 생성되는 게 GeneratedAppGM과 GlideApp인 것으로 보아 GlideApp을 사용하기 위해서 쓰이는 걸로 보인다.

(참고로 app/proguard-rules.pro 파일에서 #으로 시작되는 라인은 주석에 해당함.)

6. GlideApp 사용예

1
2
3
4
GlideApp.with(context)
.load("url")
.apply(options)
.into(imageView);

GlideApp을 통해 이미지를 로드해야지만이 CustomGlideModule에서 정의한 설정을 따른다.

기본적으로 Glide와 사용에 지장이 있을 정도로 방식이 다르지 않다.

단, GlideApp은 Glide와는 다르게 일부 RequestOptions를 통해서만 호출할 수 있었던 속성들을 다이렉트로 컨트롤할 수 있게 된다. 이는 공식문서에서 일부 예제들을 통해 비교할 수 있다.

Author

LEEJS

Posted on

2022-02-05

Updated on

2022-02-16

Licensed under

댓글