-
Notifications
You must be signed in to change notification settings - Fork 11
Description
PEKO 3.0.1
If I request permission on a fresh app startup where permissions has not been requested previously, then the app is stuck in a deadlock style ANR. It never proceeds. The same code I run works when I execute it via button press later
private val permissionRequester = PermissionRequester.instance() // Creates new instance
fun register() {
CoroutineScope(Dispatchers.Main).launch {
permissionRequester.request(android.Manifest.permission.ACCESS_FINE_LOCATION)
.collect {
// MyStuff - It never arrives to collect when deadlocked
}
}
}
Debugging indicates that it hangs after executing PermissionRequester:75 which is this line
val requester = requesterFactory.getRequesterAsync(requireContext()).await()
And the PekoActivity executes onPostCreate (with non-null requesterDeferred) but neither requestPermissions, onRequestPermissionsResult nor finish got executed on PekoActivity according to my breakpoints. Apparantly your maven upload included the source-code, so IntelliJ could debug it which was pretty cool.
If I change the code so it performs the request on another thread, then it works
fun register() {
CoroutineScope(Dispatchers.Main).launch {
// do my stuff on main (if needed, otherwise we could just create the above coroutine on IO or elsewhere
withContext(Dispatchers.IO) { // this works, no deadlock
permissionRequester.request(android.Manifest.permission.ACCESS_FINE_LOCATION)
.collect {
withContext(Dispatchers.Main) {
// do my stuff back on mair
}
}
}
}
}
After changing to the above code, the coroutine proceeded past the PermissionRequester:75 await line, performed the permission-requests and then things ran along fine from there.
For some reason the main-thread code only hung when I executed during my startup work (but long after onCreate), but did not hang when executed from user button click. But then again, that just indicates deadlocks can be tricky.
Its quite unclear to me how it can be a deadlock, as your coroutines seem fine. They suspend and should allow the main to do its work.
I have no idea if you can make any sense of that. I'll probably roll back to v2 though that had a resume rare bug, but for now I'll skip requesting permission on startup and let the user trigger it.
if you changed your library to the following I suspect it would work:
val asyncRequester = requesterFactory.getRequesterAsync(requireContext())
val requester =
withContext(Dispaters.IO) {
asyncRequester.await()
}
Best Alex