実現したいこと
作成中のアプリ内に時間のかかる処理があるのですが、その処理が終わるのを待ってから次の処理へ行くようなプログラムを実装したいです。
処理の呼び出しの例は以下です。
kotlin
1// 関数の呼び出し部分 2// 下記のように、1行目の処理を終えてから、その結果を踏まえて2行目の処理を行いたい 3currentPlaceInfoViewModel.updateCurrentPlaceInfo() 4weatherInfoViewModel.loadWeatherInfo(currentPlaceInfoViewModel.lat, currentPlaceInfoViewModel.lon)
上記の1行目の処理は、端末の現在位置の緯度経度を取得し、それらの値をcurrentPlaceInfoViewModelが持つ変数(latとlon)にセットする処理です。そして1行目でセットした値を2行目の引数として扱いたいため、1行目の処理(時間のかかる処理)を終えたのちに2行目の処理を実行したいです。
抱えている問題
上記のコードの1行目の処理(緯度経度の取得、currentPlaceInfoViewModelの持つ変数への値のセット)の結果を待たずして2行目が呼び出されてしまい、2行目の引数に意図した値を設定できません。
ソースコード
時間のかかる処理:updateCurrentPlaceInfo関数内のplacesClient.findCurrentPlace(request)
placeResponse.addOnCompleteListenerで設定した処理は、placesClient.findCurrentPlace(request) が完了した時に呼び出されます。
kotlin
1fun updateCurrentPlaceInfo() { 2 // Use fields to define the data types to return. 3 val placeFields: List<Place.Field> = listOf(Place.Field.LAT_LNG) 4 5 // Use the builder to create a FindCurrentPlaceRequest. 6 val request: FindCurrentPlaceRequest = FindCurrentPlaceRequest.newInstance(placeFields) 7 8 // Call findCurrentPlace and handle the response (first check that the user has granted permission). 9 if (ContextCompat.checkSelfPermission(getApplication<Application>(), Manifest.permission.ACCESS_FINE_LOCATION) == 10 PackageManager.PERMISSION_GRANTED) { 11 12 val placesClient = Places.createClient(getApplication<Application>()) 13 val placeResponse = placesClient.findCurrentPlace(request) //おそらくここの処理が時間がかかっている 14 15 //時間のかかる処理が完了した時に呼ばれるリスナーを追加している部分 16 placeResponse.addOnCompleteListener { task -> 17 if (task.isSuccessful) { 18 Log.d("placeResponse", "success") 19 val mostAccurateCurrentPlaceInfo = getMostAccurateCurrentLocation(task) 20 val latResult = mostAccurateCurrentPlaceInfo?.place?.latLng?.latitude 21 val lonResult = mostAccurateCurrentPlaceInfo?.place?.latLng?.longitude 22 23 // ここで緯度経度の値をcurrentPlaceInfoViewModelが持つ変数(_latと_lon)にセットしている 24 // セットした_latと_lonを、この関数(updateCurrentPlaceInfo())が呼び出された後の処理の引数として使いたい 25 if (latResult != null && lonResult != null) { 26 _lat = latResult 27 _lon = lonResult 28 } 29 30 } else { 31 val exception = task.exception 32 if (exception is ApiException) { 33 Log.d(ContentValues.TAG, "Place not found: ${exception.statusCode}") 34 } 35 } 36 } 37 38 } else { 39 Log.d("CurrentPlaceInfoVM", "not granted") 40 }
kotlin
1// 上記の関数の呼び出し部分 2// 下記のように、1行目の処理を終えてから、その結果を踏まえて2行目の処理を行いたい 3currentPlaceInfoViewModel.updateCurrentPlaceInfo() 4weatherInfoViewModel.loadWeatherInfo(currentPlaceInfoViewModel.lat, currentPlaceInfoViewModel.lon)
試したこと
色々調べた所、下記の資料に書いてあるCoroutinesという機能を使うとこの問題を解決できそうだということは分かりました。
(参考にした資料:https://droidkaigi.github.io/codelabs-kotlin-coroutines-ja/#3)
しかし、時間のかかる処理(placesClient.findCurrentPlace(request))を、どうやって参考資料のようにsuspend関数にするのかがよく分からす、解決には至っていません。
あなたの回答
tips
プレビュー