前提・実現したいこと
プログレスバーの表示→コルーチンの処理→完了したらプログレスバーの非表示という流れのプログラムを作りたい。
※プログレスバーの表示非表示の処理自体は出来ています。
発生している問題・エラーメッセージ
プログレスバーの表示が完了する前にコルーチンの処理が始まってしまう。
・実現したいことの例でいうと
プログレスバーの表示(処理途中)→コルーチンの処理→
完了したらプログレスバーの表示→表示直後にプログレスバーの非表示
というプログラムの流れになってしまっている(恐らくですが)
該当のソースコード
・LoginViewModel
kotlin
1class LoginViewModel(application: Application) : AndroidViewModel(application) { 2 3 private val scope = CoroutineScope(Dispatchers.Default) 4 5 var input_password: MutableLiveData<String> = MutableLiveData("") 6 var input_email: MutableLiveData<String> = MutableLiveData("") 7 8 fun sendJsonData() { 9 10 val apiUrl = getApplication<Application>().getString(R.string.api_url) 11 var returnParam: AccountSignin 12 13 val service: LoginApi = Repository().getLoginRetrofit(apiUrl) 14 15 val login = Login(input_password.value!!, input_email.value!!) 16 scope.launch { 17 try { 18 returnParam = service.postSignin(login) 19 Log.d("入力内容確認!", input_password.value + "/" + input_email.value) 20 Log.d("レスポンス内容!", returnParam.accessToken + "/" + returnParam.userId) 21 22 //DBのアクセストークン登録or更新 23 val loginEntity = 24 LoginEntity.login_data(returnParam.userId, returnParam.accessToken) 25 26 val user_data = GolfLocalDatabase.getInstance(getApplication()).loginDao() 27 .dataSearch(returnParam.userId) 28 if (user_data == null) { 29 GolfLocalDatabase.getInstance(getApplication()).loginDao() 30 .insert(loginEntity) 31 } else { 32 GolfLocalDatabase.getInstance(getApplication()).loginDao() 33 .updateToken(returnParam.userId, returnParam.accessToken) 34 } 35 36 } catch (e: HttpException) { 37 Log.d("Httpエラー", e.response()!!.errorBody()!!.string()) 38 39 } catch (e: Exception) { 40 Log.d("コルーチンエラー", e.toString()) 41 } 42 } 43 } 44}
試したこと
そもそも scope.launch ではメインスレッドは止まらないのでプログレスバーの表示完了後、すぐにプログレスバーの非表示処理が走ることは理解できています。
しかし、runBlockingでコルーチンが終わるのを待つ処理に変更すると
//DBのアクセストークン登録or更新 val loginEntity = LoginEntity.login_data(returnParam.userId, returnParam.accessToken) val user_data = GolfLocalDatabase.getInstance(getApplication()).loginDao() .dataSearch(returnParam.userId) if (user_data == null) { GolfLocalDatabase.getInstance(getApplication()).loginDao() .insert(loginEntity) } else { GolfLocalDatabase.getInstance(getApplication()).loginDao() .updateToken(returnParam.userId, returnParam.accessToken) }
ここでDBに接続する処理を実装しているので
Cannot access database on the main thread since it may potentially lock the UI for a long period of time
というエラーが発生してしまい runBlocking での実装が上手く出来ません。
整理すると
1、プログレスバーの表示が完了してからコルーチンの処理を走らせる
2、runBlockingを使わずにコルーチンの処理完了後にプログレスバーの非表示(runBlockingを用いた処理が可能でしたら runBlocking を用いた処理を行いたいです)
以上の2点を実現したいです。
他に確認したいファイル等ありましたら教えてください。
1点だけの解決、また scope.launch ではなく runBlocking を用いた処理でないといけないといった説明も大歓迎ですのでご教示をお願いしたいです。
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/02/16 16:30 編集
2021/02/16 16:39 編集
2021/02/16 22:59
2021/02/16 23:13
2021/02/17 01:08