티스토리 뷰

요즘 이래저래 정신이 없어,

많은 글을 쓰지 못하고 있다. ㅜㅜ


개발하다보면, 네트워크를 사용하여 원격 저장소에 있는 이미지를 가져와,

노티에 뿌려줘야하는 경우가 있다.

이미지 레이지로딩을 할 수 있는 많은 오픈 소스가 있는데,

오늘은 Glide 를 사용하여 띄우는 방법에 대해 남겨볼까 한다!


사실 글라이드 모듈에서는 NotificationTarget 이라는 굉장이 편리한 클래스를 제공한다.


private void imageLoadNotification( Context context, Notification notification, String imgPath ) {

if( context == null || notification == null ) {
return;
}
NotificationManager manager = (NotificationManager)

context.getSystemService(Context.NOTIFICATION_SERVICE);

if( manager == null ) {
return;
}

NotificationTarget notificationTarget = new NotificationTarget(context,
notification.contentView, 이미지뷰 아이디, notification, 노티피케이션 아이디);

Glide.with(context.getApplicationContext())
.asBitmap()
.load(imgPath)
.into(notificationTarget);
}


위와 같이 사용하면 굉장히 간편하다.


But!!!

이렇게 쉬우면 기록하지도 않았을 것이다.


네트워크 및 원격 저장소의 상태에 따라 노티 갱신이 느려질 수 있는데,

Oreo 부터 백그라운드 서비스 시작 시 5초 안에 서비스를 포어그라운드로 승격 시키지 않으면 ANR 오류를 막 뱉어 내는 것이었다.

처음엔 간단하게 Glide 호출 전 먼저 한번 노티를 올려 주고 호출하는 방식으로 수정하였으나,

오류를 잡은 대신 깜박임을 얻게 되었다. OTL


때문에 그냥 하나 만들었다.


class NotificationGlideHelper {
NotificationGlideHelper(Context context, Notification notification, String imgPath) {
if( context == null || notification == null || notification.contentView == null || TextUtils.isEmpty(imgPath)) {
return;
}
requestImage(context, notification, imgPath, true);
}

private void requestImage( final Context context, final Notification notification,
final String imgPath, final boolean isTimeOut ) {
try {
RequestOptions moduleOption = new RequestOptions()
.error(디폴트이미지)
.diskCacheStrategy(DiskCacheStrategy.AUTOMATIC);
// TimeOut 을 3초로 줘서 OS 8.0 백그라운드 서비스 시작시 포어그라운드 에러를 방지한다.
// 요 옵션은 네트워크 read / write 타임아웃이지 connection 타임아웃이 아니므로 한계가 존재한다.
// Glide connection 타임아웃 관련해서는 추후 보강하자!
if( isTimeOut )
moduleOption.timeout(3000);
// glide 비트맵 콜백
SimpleTarget<Bitmap> glideNotificationTarget = new SimpleTarget<Bitmap>() {
@Override
public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
try {
if( notification != null && notification.contentView != null ) {
notification.contentView.setImageViewBitmap(이미지뷰 아이디, resource);
}
}catch ( Exception e ) {
// Exception
}finally {
updateNotification(context, notification);
}
}

@Override
public void onLoadFailed(@Nullable Drawable errorDrawable) {
updateNotification(context, notification);
requestImage(context, notification, imgPath, false);
}
};

// 이미지 로딩
Glide.with(context.getApplicationContext())
.asBitmap()
.load(imgPath)
.apply(moduleOption)
.into(glideNotificationTarget);

}catch ( OutOfMemoryError oom ) {
// OOM이 발생하면, 메모리를 클리어 시키고 재요청 하자.
Glide.get(context.getApplicationContext()).clearMemory();
updateNotification(context, notification);
}catch ( Exception e ) {
updateNotification(context, notification);
}
}

// 실제 노티피케이션을 올리는 함수
private void updateNotification( Context context, Notification notification ) {
if( context == null || notification == null ) {
return;
}
NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
if( manager == null ) {
return;
}

manager.notify(노티피케이션 아이디, notification);
((Service) context).startForeground(노티피케이션 아이디, notification);
}

}

요로케 쓰면 Oreo ANR 을 회피할 수 있땅~~~

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/08   »
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
글 보관함