registerForActivityResult能在协程中使用吗?

4
我认为存在的问题是必须保证在您自己的activity的OnCreate()完成之前调用registerForActivityResult()。很明显,OnCreate()不是一个挂起函数,因此我不能将registerForActivityResult()和ActivityResultLauncher.launch()包装在suspendCoroutine{}中以等待回调,因为我无法从OnCreate()启动suspendCoroutine并等待其完成后才让OnCreate()完成...这是我的看法。
我曾经认为使用runBlocking{}可以实现这一点,但我发现在OnCreate()内调用runBlocking会导致应用程序永远挂起,而且永远不会运行runBlocking{}块中的代码。
所以我的问题是,我是否使用了正确的方法实现 runBlocking{},或者是否有其他使用registerForActivityResult()在协程中的方法,或者根本不可能。

你尝试过在onCreate中使用runBlocking(IO) {}吗?这样可以阻塞IO线程而不是UI线程。 - Stachu
不要这样做。Runblocking会阻塞调用它的线程。在Android应用程序中,永远不应该使用Runblocking。 - Tenfour04
无论你想做什么都是不可能的。onCreate 不能等待 Activity 结果,因为下一个 Activity 只能在此 Activity 创建后才能启动。 - Tenfour04
1个回答

7
你可以像这样做。请参考下面的实现。
class RequestPermission(activity: ComponentActivity) {
    private var requestPermissionContinuation: CancellableContinuation<Boolean>? = null
    @SuppressLint("MissingPermission")
    private val requestFineLocationPermissionLauncher =
        activity.registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted ->
            requestPermissionContinuation?.resumeWith(Result.success(isGranted))
        }

    suspend operator fun invoke(permission: String) = suspendCancellableCoroutine<Boolean> { continuation ->
        requestPermissionContinuation = continuation
        requestFineLocationPermissionLauncher.launch(permission)
        continuation.invokeOnCancellation {
            requestPermissionContinuation = null
        }
    }
}

请确保在 Activity 的 onStart 之前初始化此类。应该在 Activity 的 onStart 之前调用 registerForActivityResult API。请参考下面的示例。

class SampleActivity : AppCompatActivity()  {
    val requestPermission: RequestPermission = RequestPermission(this)

    override fun onResume() {
        super.onResume()
        lifecycleScope.launch {
            val isGranted = requestPermission(Manifest.permission.ACCESS_FINE_LOCATION)
            //Do your actions here
        }

    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接