permissions-dispatcher / PermissionsDispatcher

A declarative API to handle Android runtime permissions.
https://github.com/permissions-dispatcher/PermissionsDispatcher
Apache License 2.0
11.22k stars 1.44k forks source link

Application crash after sending it to background (process kill) #723

Closed jczerski closed 3 years ago

jczerski commented 3 years ago

Overview

At the very beginning I would like you thank you for great library which solves developer problems in a beautiful style.

I found a problem when system permission dialog appears and we put app to the background.

Code snippet for fragment (for activity is same behaviour):

class TestFragment : Fragment() {

    private lateinit var locationPermissionRequester: PermissionsRequester

    override fun onAttach(context: Context) {
        super.onAttach(context)
        locationPermissionRequester = constructLocationPermissionRequest(LocationPermission.FINE) {
            // do nothing
        }
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        locationPermissionRequester.launch()
    }
}

Stacktrace:

java.lang.RuntimeException: Unable to start activity ComponentInfo{my.app.debug/my.app..RootActivity}: java.lang.IllegalStateException: FragmentManager is already executing transactions
   android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3270)
   android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
   android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
   android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
   android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
   android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
   android.os.Handler.dispatchMessage(Handler.java:107)
   android.os.Looper.loop(Looper.java:214)
   android.app.ActivityThread.main(ActivityThread.java:7356)
   java.lang.reflect.Method.invoke(Native Method)
   com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
   com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
Caused by:
java.lang.IllegalStateException: FragmentManager is already executing transactions
   androidx.fragment.app.FragmentManager.ensureExecReady(FragmentManager.java:1919)
   androidx.fragment.app.FragmentManager.execSingleAction(FragmentManager.java:1955)
   androidx.fragment.app.BackStackRecord.commitNowAllowingStateLoss(BackStackRecord.java:311)
   permissions.dispatcher.ktx.PermissionRequestFragment.dismiss(PermissionRequestFragment.kt:26)
   permissions.dispatcher.ktx.PermissionRequestFragment$NormalRequestPermissionFragment.onRequestPermissionsResult(PermissionRequestFragment.kt:56)
   androidx.fragment.app.FragmentManager$11.onActivityResult(FragmentManager.java:2951)
   androidx.fragment.app.FragmentManager$11.onActivityResult(FragmentManager.java:2923)
   androidx.activity.result.ActivityResultRegistry.doDispatch(ActivityResultRegistry.java:362)
   androidx.activity.result.ActivityResultRegistry.dispatchResult(ActivityResultRegistry.java:322)
   androidx.activity.ComponentActivity.onRequestPermissionsResult(ComponentActivity.java:654)
   androidx.fragment.app.FragmentActivity.onRequestPermissionsResult(FragmentActivity.java:604)
   android.app.Activity.requestPermissions(Activity.java:5083)
   androidx.core.app.ActivityCompat.requestPermissions(ActivityCompat.java:516)
   androidx.activity.ComponentActivity$2.onLaunch(ComponentActivity.java:195)
   androidx.activity.result.ActivityResultRegistry$3.launch(ActivityResultRegistry.java:219)
   androidx.activity.result.ActivityResultLauncher.launch(ActivityResultLauncher.java:47)
   androidx.fragment.app.FragmentManager.launchRequestPermissions(FragmentManager.java:3028)
   androidx.fragment.app.Fragment.requestPermissions(Fragment.java:1559)
   permissions.dispatcher.ktx.PermissionRequestFragment$NormalRequestPermissionFragment.onCreate(PermissionRequestFragment.kt:32)
   androidx.fragment.app.Fragment.performCreate(Fragment.java:2936)
   androidx.fragment.app.FragmentStateManager.create(FragmentStateManager.java:472)
   androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:278)
   androidx.fragment.app.FragmentStore.moveToExpectedState(FragmentStore.java:112)
   androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1636)
   androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:3112)
   androidx.fragment.app.FragmentManager.dispatchCreate(FragmentManager.java:3045)
   androidx.fragment.app.FragmentController.dispatchCreate(FragmentController.java:240)
   androidx.fragment.app.FragmentActivity.onCreate(FragmentActivity.java:272)
   my.app.RootActivity.onCreate(RootActivity.kt:147)
   android.app.Activity.performCreate(Activity.java:7802)
   android.app.Activity.performCreate(Activity.java:7791)
   android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1299)
   android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3245)
   android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
   android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
   android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
   android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
   android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
   android.os.Handler.dispatchMessage(Handler.java:107)
   android.os.Looper.loop(Looper.java:214)
   android.app.ActivityThread.main(ActivityThread.java:7356)
   java.lang.reflect.Method.invoke(Native Method)
   com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
   com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)

Expected

Actual

Environment

Reproducible steps

  1. To make it easier to reproduce this bug, turn on "Don't keep activities" in developer options
  2. Run the app with activity or fragment with permission
  3. When pop up asking about permission will appear, send app to background
  4. Return to the app

Thank you for the help in advance. Jack

hotchemi commented 3 years ago

thx, I could repro 🙏

jczerski commented 3 years ago

@hotchemi thank you for review and I'm waiting for release 😃

jczerski commented 3 years ago

@hotchemi can we expect ktx 1.0.5 release ?:)

hotchemi commented 3 years ago

sure I'll do!