[코드 리팩토링] '미주정복' 5일차 - 에러 수정, SettingScreen

이윤진·2024년 1월 18일
0

코드 리팩토링

목록 보기
6/12

어제 발생한 에러

java.lang.RuntimeException: Cannot create an instance of class com.example.usdividend.view.stock.StockViewModel
에러가 앱을 실행시키자 나타났다.
이는 내가 StockViewModel에 @HiltViewModel을 넣어주지 않아 생긴 에러였다.

java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
위의 에러를 해결하고 나니 새로운 에러가 나왔다.
이는 내가 Database에 접근하는 에러를 ViewScoped.launch에서 실행하게 하도록 설정해서 그렇다 이 부분을 Coroutine(Dispatchers.IO)로 바꾸니 해결되었다.

또 에러가 발생했다.
java.lang.NullPointerException: Attempt to invoke virtual method 'void androidx.lifecycle.MutableLiveData.setValue(java.lang.Object)' on a null object reference

https://stackoverflow.com/questions/72860457/attempt-to-invoke-virtual-method-void-androidx-lifecycle-mutablelivedata-setval
위의 해결법으로 Init을 가장 아래에 배치하여 해결했다.

java.lang.IllegalStateException: Cannot invoke setValue on a background thread

https://bacassf.tistory.com/133
위와 같은 방법으로 postValue를 사용해서 해결했다.
setValue는 UI 쓰레드를 사용하고 postValue는 백그라운드 쓰레드를 사용하기 때문에 생기는 차이라고 한다.

기존 SettingScreen 구조

  1. compose 함수
  2. 서버 통신 retrofit 함수
  3. 로그아웃 메서드

바뀐 SettingView 구조

SettingScreen에서 SettingView로 파일 명과 함수 명을 변경하였다.
SettingViewModel을 만들어 데이터를 다루는 부분은 이 파일에서 개발하였다.
서버와 통신하는 부분은 데이터베이스에서 값을 가져오는 것으로 변경했다.

SettingView

먼저 SettingTop, SettingAccount와 같이 애매한 함수 명을 SettingTitle, SettingEmail로 변경하였다.
또, LogoutDialog의 표시 여부를 결정하는 변수명을 LogoutIsClicked로 변경하여 정확하게 어떤 것을 의미하는지 알기 쉽게 하였다.

SettingViewModel

데이터베이스에서 이름과 이메일을 가져오는 메서드를 만들었다.

    private val _nickname = MutableLiveData<String>()
    val nickname : LiveData<String> get() = _nickname

    private val _email = MutableLiveData<String>()
    val email : LiveData<String> get() = _email

    fun getNickname() = CoroutineScope(Dispatchers.IO).launch{
        _nickname.postValue(userDao.getName(0))
    }

    fun getEmail() = CoroutineScope(Dispatchers.IO).launch {
        _email.postValue(userDao.getEmail(0))
    }

LogoutDialog

로그아웃을 누르면, 로그아웃 하시겠습니까? 하는 로그아웃 다이얼로그가 표시된다.
다이얼로그도 View와 ViewModel을 구분하기 위해 다이얼로그가 SettingViewModel을 사용할 수 있도록 바꾸었다.

@Composable
fun LogoutDialog(
    settingViewModel: SettingViewModel = hiltViewModel()
)

그리고 SettingViewModel에서 작동 함수를 만들었다.

    fun logout(){
        val intent = Intent(context, LoginActivity::class.java)
        intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
        ContextCompat.startActivity(context, intent, null)
    }
profile
Android/Flutter 개발

0개의 댓글