Faktycznie, trzeba trochę się namęczyć, żeby wydzielić HMS billing do osobnej klasy, przez używanie onActivityResult.Ja u siebie zrobiłem do tego taki mały hack, przy pomocy daggera.
Zrobiłem sobie klasę o nazwie ActivityResultObserver, która żyje w scope aktywności. Wygląda to mniej więcej tak:
Później musisz wstrzyknąć tę klasę w aktywności, która będzie otrzymywać rezultat.
@Inject
lateinit var activityResultObserver: ActivityResultObserver
Oraz przekazać rezultat z onActivityResult (w tej samej aktywności co wcześniej wstrzykiwaliśmy zależność)
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
activityResultObserver.onResultReceived(requestCode, resultCode, data)
}
Później w swojej klasie, zajmującej się obsługą billingu deklarujesz sobie result receiver, na przykład tak:
private val huaweiIdLoginInResultReceiver: ResultReceiver = { resultCode: Int, data: Intent? ->
//akcja po przyjściu rezultatu
}
I dodajesz go, przed wywołaniem akcji HMS, na przykład tak:
activityResultObserver.addResultReceiver(
HUAWEI_ID_LOG_IN_REQUEST_CODE,
huaweiIdLoginInResultReceiver
)
//akcja HMS wymagająca obsługi onActivityResult
Pamiętaj, żebyActivityResultObserver nie żył dłużej, niż sama aktywność, bo może to doprowadzić do wycieków pamięci.
Co do problemu z callbackami, można to łatwo ogarnąć przy pomocy suspend coroutine, na przykłąd tak jak tutaj:
private suspend fun checkEnvReady() =
suspendCoroutine { coroutineContinuation: Continuation<Unit> ->
client.isEnvReady
.addOnSuccessListener {
coroutineContinuation.resume(Unit)
}
.addOnFailureListener {
coroutineContinuation.resumeWithException(it)
}
}