문제 상황
java.lang.NullPointerException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkNotNullParameter, parameter think
아이템 삭제 버튼을 클릭하면 NullPointerException 발생
해결 과정
첫번째로 했던 일은 Logcat 을 살펴보면 링크로 ThinkPresenter 의 getThink() 메소드를 가리키길래 거기서 문제가 있나 싶었다.
그런데 삭제를 했는데 getThink() 가 다시 호출이 되나? 싶어서 아래의 사진과 같이 삭제를 했을때의 흐름을 살펴보았다.
예상했던 화면 흐름은
삭제를 마치고 popBackStack() 을 하면 바로 생각 리스트로 돌아간다고 예상했지만, 호락호락하지 않은 놈 ..
중간에 한 과정을 생각하지 못했다.
삭제 다이얼로그가 끝나면 원래 사용자에게 보여졌던 생각 화면(4번째)이 보여진 후, 생각 목록(5번째)로 넘어가게 된다.
popBackStack() 을 해서 사용자에게는 생각 화면(4번째)가 보이지 않겠지만, 이를 처리해주어야 한다는 것을 알게되었다.
sealed class ThinkUiState {
object Loading: ThinkUiState()
data class Success(val think: Think) : ThinkUiState()
data class Failed(val tag: String, val message: String?) : ThinkUiState()
}
그래서 Ui 데이터를 담당했던 UiState 클래스의 Success 부분의 think 매개변수를 nullable 하도록 변경해주었다.
sealed class ThinkUiState {
object Loading: ThinkUiState()
data class Success(val think: Think?) : ThinkUiState()
data class Failed(val tag: String, val message: String?) : ThinkUiState()
}
null 인 값도 들어올 수 있도록 매개변수에 ?를 붙여주면 끝!
private fun showThink(thinkId: Long) {
presenter.getThink(thinkId)
lifecycleScope.launch {
(presenter as ThinkPresenter).thinkUiState.collectLatest {
when(it) {
is ThinkUiState.Loading -> { }
is ThinkUiState.Success -> {
binding.thinkToolbar.title = "${args.position + 1}번째 생각"
binding.thinkContents.apply {
setText(it.think.think)
}
binding.thinkDate.text = it.think.registDate.substring(0, 10)
showMultiDialog(it.think)
}
is ThinkUiState.Failed -> { }
}
}
}
}
생각 화면에서 Success 를 처리해주던 부분에서도 null 을 처리할 수 있도록 아래와 같이 수정해주었다.
private fun showThink(thinkId: Long) {
presenter.getThink(thinkId)
lifecycleScope.launch {
(presenter as ThinkPresenter).thinkUiState.collectLatest {
when(it) {
is ThinkUiState.Loading -> { }
is ThinkUiState.Success -> {
if(it.think == null) {
binding.root.findNavController().popBackStack()
} else {
binding.thinkToolbar.title = "${args.position + 1}번째 생각"
binding.thinkContents.apply {
setText(it.think.think)
}
binding.thinkDate.text = it.think.registDate.substring(0, 10)
showMultiDialog(it.think)
}
}
is ThinkUiState.Failed -> { }
}
}
}
}
null 의 값이 들어오면 삭제가 되었다는 의미이므로 popBackStack() 으로 처리해주었다!
결과 화면
'Android > note' 카테고리의 다른 글
Coroutine + LiveData 를 통해 데이터 전달받기 그런데 이전 데이터도 전달되는 .. (3) | 2024.01.26 |
---|---|
URL 에 콜론(:), 더하기(+)와 같은 문자가 포함되었을 때 (1) | 2024.01.03 |
[Android] Room Database 버전 올리기 그런데 오류를 곁들인 .. (Migration didn't properly handle) (0) | 2023.09.15 |
[Android] EditText 의 데이터 Intent 로 받아오기 (0) | 2023.09.15 |
[Android] MVP 디자인 패턴에서 View 와 Presenter 는 왜 꼭 1:1로 대응되어야 할까? (0) | 2023.09.10 |