Есть ли хороший способ преобразовать обратный вызов StartActivityResult в композиции в линейный стиль Coroutine?Android

Форум для тех, кто программирует под Android
Ответить
Anonymous
 Есть ли хороший способ преобразовать обратный вызов StartActivityResult в композиции в линейный стиль Coroutine?

Сообщение Anonymous »

Я столкнулся с проблемой проектирования компоновки + сопрограммы.
Предположим, у меня есть кнопка создания композиции, и после того, как я нажму ее, мне нужно запуститьActivityResult для другого приложения и выполнить обратный вызов после Я получил от этого результат.
Самая важная часть — я хочу, чтобы это было в линейном стиле, например, с помощью suspendCancellableCoroutine.
Я знаю, как справиться с этим в случае отсутствия композиции это выглядит так:

Код: Выделить всё

private var mContinuation:Continuation? = null

private val launcher = launcherRegister(
onResult = {result ->
mContinuation?.resume(result)
}
)

private fun launcherRegister(
onResult: (Boolean) -> Unit,
) = registerForActivityResult(ActivityResultContracts.StartActivityForResult()){ activityResult: ActivityResult ->
onResult(activityResult.resultCode == Activity.RESULT_OK)
}

override fun onCreateView(...):View{
//...
textView.setOnClickListener {
goo(
onPostExecute = { Log.d("Timothy", "onPostExecute")},
onPreExecute = { Log.d("Timothy", "onPreExecute")},
onSuccess = {Log.d("Timothy","onSuccess")},
scope = lifecycleScope,
intent = Intent(Settings.ACTION_WIFI_SETTINGS)
)
}
//...
}

suspend fun foo(intent:Intent):Boolean = suspendCancellableCoroutine{cont->
mContinuation = cont
cont.invokeOnCancellation{
launcher.unregister()
mContinuation = null
}
launcher.launch(intent)
}

fun goo(
onPreExecute: () -> Unit,
onPostExecute: () -> Unit,
onSuccess: () -> Unit,
scope: CoroutineScope,
intent: Intent
){
scope.launch {
withTimeout(10_000){
onPreExecute()
val success = foo(intent)
if(success){
onSuccess()
}
onPostExecute()
}
}
}
Но я застрял в rememberLauncherForActivityResult композиции.
suspendCancellableCoroutine нужно делать с модификатором приостановки, а компонуемая функция не должна его нельзя приостановить.
Мне интересно, есть ли хороший способ получить результат активности из другого приложения в области создания и сделать это в линейном стиле?
Спасибо.
[обновление 10 мая 2024 г.]
Спасибо, что напомнили о @JanBína. Код, который я предоставил ранее, очень неправильный. Из документации:

"Это необходимо вызывать безоговорочно, как часть пути инициализации,
обычно как инициализатор поля действия или фрагмента. "

Обновляю вторую версию.

Подробнее здесь: https://stackoverflow.com/questions/784 ... se-to-coro
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Android»