Android Support library 27.0.x 와 @Nullable hell
앱을 릴리즈 한 이후 아래와 같은 크래시가 수집되었다.
Fatal Exception: java.lang.NoClassDefFoundError: android/graphics/drawable/Icon
at java.lang.Class.getDeclaredMethods(Class.java)
at java.lang.Class.getDeclaredMethods(Class.java:656)
at android.view.ViewDebug.getExportedPropertyMethods(ViewDebug.java:960)
건수가 많지도 않고, 삼성 특정 os 버전에서만 발생하는 이슈였다. 뭔가 stack도 좀 이상하고. ViewDebug가 왜 나오지?
혹시 몰라 stackoverflow를 뒤져보니 이미 누군가가 이 에러로 고민하고 있었고, 해결책도 나와있다.
- Support library 25.4.0 에서
setImageIcon
을 잘 못 override 했었다. - Support library 27.0.0 에서 수정되었으니 Support library를 27로 올려라.
support library 는 지금 시점에 27.0.2 와 27.1.0 이 최신 버전이다. 하지만 x.x.0
버전은 쓰는게 아니라고 몸으로 (그리고 크래시로) 익혀왔기 때문에 27.0.2 로 support library를 올렸다.
support library 버전 교체는 대게 아무 문제없이 끝나는데, 무수한 컴파일 에러가 난다. 뭐가 문젠가 하고 봤더니 Fragment 관련 코드에 @Nullable, @NonNull 애노테이션이 추가되어, 이를 사용하는 kotlin 측 코드의 nullability 부분이 와장창 깨졌다. 하지만 이게 옳은 방향이니 내가 수정해야지 뭐.
이걸 어떻게 대응하나 싶어 간단히 구글링 해 보니 reddit 에선 누군가가 이를 nullable hell
이라고 표현했다. 딱 맞는 표현이네.
여기저기서 비명을 외쳐대는걸 구글이 들었는지, 27.1.0 에는 아래와 같은 기능이 추가되었다.
Fragments now have requireContext(), requireActivity(), requireHost(), and requireFragmentManager() methods, which return a NonNull object of the equivalent get methods or throw an IllegalStateException.
requireViewById(), a @NonNull compat version of findViewById() has been added to WindowCompat, ActivityCompat, and ViewCompat, which throw an IllegalArgumentException when the target cannot be found.
근데 null check를 하고 사용하는게 나을지, require*
을 쓰고 try-catch를 하는게 나을지 좀 아리까리하네. getActivity()
를 호출하고, null check를 직접 하는게 낫지 않나?
tag에 kr-dev 추가하시는 걸 추천합니다 ^^