안드로이드 앱 개발기 #31 - RxJava2 사용하며 만난 NullPointerException: The mapper function returned a null value.
RxJava2 라이브러리가 제공하는 Observable.map 메소드를 호출하는 코드에서 다음과 같은 예외가 발생했습니다.
java.lang.NullPointerException: The mapper function returned a null value.
예외가 발생하면, 그것이 일어난 위치를 Logcat에서 보통 볼 수 있습니다. 그 위치는 내 소스 파일의 몇번째 줄이라고 친절하게 알려주는데요. 이번 예외에서는 그게 드러나지 않아서 잠시 당황했습니다.
Observable 인터페이스의 map 메소드에 관해....
서버 연동 라이브러리는 retrofit2를 사용하고 있구요. 서버로부터 데이터를 구독하기 위해 RxJava2도 활용하고 있습니다. 서버로부터 받은 데이터는 그것을 바로 활용하기도 하지만요. 그것에는 앱이 필요로 하는 내용 외에 다른 자료들도 많이 갖고 있는 경우가 많습니다. 앱 입장에서 그런 것은 불필요하기 때문에 앱이 필요로 하는 포맷으로 재가공합니다. 재가공을 위해 자주 사용하는 메소드는 Observable 인터페이스의 map입니다.
NullPointerException의 원인
오류 메시지의 원인을 이해하는 것이 문제 해결의 시작이었습니다.
The mapper function returned a null value.
제 코드에서는 Observable 인터페이스의 map 메소드를 사용하고 있었구요. 그것을 호출할 때 사용되는 람다식을 확인해 보니 실제로 null 값을 리턴하는 케이스가 있음을 발견했습니다. 원래는 리스트를 리턴해야 하는데, 서버에서 리스트를 주지 않는 것이 원인이었습니다.
해결책
서버에서 빈 리스트를 주는 것이 원래는 제일 좋지만, 이 문제는 map 메소드의 람다식에서 null 대신 다른 값을 리턴하면 됩니다. 만약 원래 리턴해야 하는 것이 리스트이고 그것이 현재 null이라면, 비어있는 리스트를 리턴하면 됩니다.
예
서버로부터 response를 받기 위한 Observable 객체 이름이 responseObservable이고, response가 list를 가지고 있다고 가정해 보겠습니다. 앱에서 list만 필요하다면, response로부터 list만 추출하면 되겠지요. 아래와 같이 map 메소드를 호출하면 됩니다.
responseObservable.map { response ->
response.list
}
그런데 위 코드에서는 list가 null인 경우를 고려하지 않고 작성한 것입니다. 이 코드를 그대로 쓰면 위에 말씀드린 NullPointerException이 발생할 수 있죠. 이를 막기 위해 list가 null이면 빈 리스트를 대신 리턴시키면 됩니다. 수정 코드는 아래와 같습니다.
responseObservable.map { response ->
response.list ?: listOf()
}
지난 안드로이드 앱 개발기
- #30 - 나이트 모드를 고려하지 않아 메인 화면 시작시 발생한 IllegalStateException
- #29 - 잊고 있었던 앱 재시작 샘플 코드
- #28 - 문자열 리소스 파일 strings.xml 어떻게 작성하면 좋을까?
- #27 - 클린 아키텍처에서 domain 모듈
- #26 - 클린 아키텍처 구현을 위한 모듈 구성
- #25 - 스팀 관련 샘플 코드 만들면서 잘못한 점
- #24 - 시작 화면 구성 요소 식별하기
- #23 - 프로젝트 초기 화면 구성부터 대략적으로...
- #22 - Kotlin 코드로 JavaScript 코드를 실행할 수 있을까?
- #21 - 실습 도중 발생한 오류: A failure occurred while executing org.jetbrains.kotlin.gradle.internal.KaptExecution
- #20 - 클립보드에 텍스트 복사하는 함수 만들어 보기 (Kotlin)
- #19 - 데이터 바인딩 적용했으나 UI 자동 업데이트 되지 않는 문제
- #18 - 에뮬레이터에서 토스트 안 보이는 문제 (1)
- #17 - 유닛 테스트를 실행할 수 없는 문제 해결
- #16 - 잘 되던 유닛 테스트를 실행할 수 없는 문제
- #15 - 앱 재시작 코드
- #14 - Fragment 사용시 간혹 발생할 수 있는 Fragment not attached to Activity 문제
- #13 - Retrofit2 활용 서버로부터 받을 데이터 유형 JsonElement (JSONObject 사용 불가)
- #12 - Glide 활용하여 이미지 다운로드 받는 코드
- #11 - 처리할 수 없는 예외/크래쉬 발생시 앱 재시작하기
- #10 - 안드로이드 스튜디오 업그레이드 후 단축키가 안되면? (맥북)
- #9 - LiveData 객체에 동일 데이터 설정하면 observer 실행되는지 확인 목적의 샘플 프로젝트
- #8 - 안드로이드 스튜디오에서 빌드시 발생하는 Build Tools revision 31.0.0 오류
- #7 - 'UGC(사용자 생성 콘텐츠) 정책 미준수'로 심사 거절
- #6 - 뷰에 역마진 적용 불가시 translationX, translationY 속성 사용하기
- #5 - 프로젝트 생성 후 빌드시 발생 오류: The minCompileSdk (31) specified in a dependency's AAR metadata
- #4 - 프로젝트 생성 후 빌드시 발생 오류: The minCompileSdk (31) specified in a dependency's AAR metadata
- #3 - 무한 롤링 배너 만드는 법을 찾았으나, 높이를 wrap_content로 지정이 안 먹히는 문제점이...
- #2 - setContentView 메소드의 파라메터를 변경하지 않아서 발생한 화면 오류
- #1 - 페이스북 로그인 연동시 발생했던 문제들
[광고] STEEM 개발자 커뮤니티에 참여 하시면, 다양한 혜택을 받을 수 있습니다.
Upvoted! Thank you for supporting witness @jswit.
![default.jpg](https://steemitimages.com/640x0/https://cdn.steemitimages.com/DQmNwBDPMPvL1yaKWTYF4wxyUmxWiEJgAy1WZWTJyCha5wE/jswit_comment_initial.w320.jpg)