profile image

L o a d i n g . . .

반응형

안드로이드 글라이드(Glide) IllegalArgumentException ~ You cannot start a load for a destroyed activity

 

 

안드로이드 이미지 로드 대표 라이브러리라고 해도 과언이 아닐 만큼 유명한 라이브러리

 

글라이드 Glide

 

글라이드 라이브러리를 사용하다보면 가끔 파이어베이스 크레쉬 리포트에 IllegalArgumentException 크레쉬가 뜨는 걸 확인 할 수 있는데, 이는 글라이드 라이브러리 내에 null체크 하는 과정에서 생기는 exception이다.

 

라고 나는 생각이 든다..

 

이를 확인할 수 있는 코드가 글라이드 라이브러리 내에서 확인을 할 수 있는데

 

RequestManagerRetriever 클래스에서

 

@Nullable
  private Activity findActivity(@NonNull Context context) {
    if (context instanceof Activity) {
      return (Activity) context;
    } else if (context instanceof ContextWrapper) {
      return findActivity(((ContextWrapper) context).getBaseContext());
    } else {
      return null;
    }
  }

코드를 통해 Activity인지와 null체크를 하는데, return이 된다면 앱이 죽지 않고, 글라이드가 아마 동작을 하지 않을 것이다. 아니면 혹은 미리 설정해둔 에러 이미지가 나온다든가..?

 

문제는 이 아래 메소드이다.

 

@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
  private static void assertNotDestroyed(@NonNull Activity activity) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 && activity.isDestroyed()) {
      throw new IllegalArgumentException("You cannot start a load for a destroyed activity");
    }
  }

if문의 마지막에 activity.isDestroyed에서 true일 경우 바로 IllegalArgumentExecption을 던지는데 이 때문에 앱이 죽고 크레쉬 리포트에는 "You cannot start a load for a destroyed activity"로그가 찍히는 것이 아닐까 싶다.

그런데 지금 다시 보니 TargetApi 어노테이션을 보았는데, 저 해당 버전에서만 저 메소드를 타는게 아닌가..?

심지어 저 안드로이드 버전을 사용하는 사람이 아직도 있는가... 

결국 activity.isDestroyed가 중요하지 않을까

 

이를 방어하기 위해서는 위 null체크구문을 타기 전에 미리 Activity인지와 null체크를 해주고 

if(!activity.isDestroyed && ...) {
	...
}

위와 같이 !isDestroyed 일 때 글라이드를 동작시켜주면 되지 않을 까 싶다. 이를 위해서는 글라이드를 공통 클래스 혹은 메소드로 빼서 관리를 해야할까 싶다.

 

glideRequestManager = GlideApp.with(this);

그런데 이는 단순한 방어로직으로 생각이 들며, activity 혹은 context를 받는 glideRequestManager을 만들어서 글라이드를 작동시키면 되지 않을까 싶다.

 

 

반응형
복사했습니다!