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

[ktx] Construct PermissionsRequester from Fragment may cause that callbacks (requiresPermission, onPermissionDenied, etc.) are called after Fragment instance is already dead #765

Open omtians9425 opened 2 years ago

omtians9425 commented 2 years ago

Overview

Reproducible steps

Stack trace:

Toast uses detached Context so java.lang.IllegalStateException: Fragment SecondFragment{9e09ebc} (c9cd8d4c-7acc-476a-90c8-7e882fc8dd69) not attached to a context. is shown

2022-02-25 01:27:24.555 21578-21578/com.example.omtians9425.permissionsdispatcherktxsample E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.omtians9425.permissionsdispatcherktxsample, PID: 21578
    java.lang.RuntimeException: Failure delivering result ResultInfo{who=@android:requestPermissions:, request=1462789988, result=-1, data=Intent { act=android.content.pm.action.REQUEST_PERMISSIONS (has extras) }} to activity {com.example.omtians9425.permissionsdispatcherktxsample/com.example.omtians9425.permissionsdispatcherktxsample.MainActivity}: java.lang.IllegalStateException: Fragment SecondFragment{9e09ebc} (c9cd8d4c-7acc-476a-90c8-7e882fc8dd69) not attached to a context.
        at android.app.ActivityThread.deliverResults(ActivityThread.java:4360)
        at android.app.ActivityThread.handleSendResult(ActivityThread.java:4402)
        at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:49)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6669)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
     Caused by: java.lang.IllegalStateException: Fragment SecondFragment{9e09ebc} (c9cd8d4c-7acc-476a-90c8-7e882fc8dd69) not attached to a context.
        at androidx.fragment.app.Fragment.requireContext(Fragment.java:919)
        at com.example.omtians9425.permissionsdispatcherktxsample.SecondFragment$onAttach$1.invoke(SecondFragment.kt:24)
        at com.example.omtians9425.permissionsdispatcherktxsample.SecondFragment$onAttach$1.invoke(SecondFragment.kt:20)
        at permissions.dispatcher.ktx.PermissionRequestViewModel$observe$1.onChanged(PermissionRequestViewModel.kt:33)
        at permissions.dispatcher.ktx.PermissionRequestViewModel$observe$1.onChanged(PermissionRequestViewModel.kt:30)
        at androidx.lifecycle.LiveData.considerNotify(LiveData.java:133)
        at androidx.lifecycle.LiveData.dispatchingValue(LiveData.java:151)
        at androidx.lifecycle.LiveData.setValue(LiveData.java:309)
        at androidx.lifecycle.MutableLiveData.setValue(MutableLiveData.java:50)
        at permissions.dispatcher.ktx.PermissionRequestViewModel.notifyObserver(PermissionRequestViewModel.kt:43)
        at permissions.dispatcher.ktx.PermissionRequestViewModel.postPermissionRequestResult(PermissionRequestViewModel.kt:20)
        at permissions.dispatcher.ktx.PermissionRequestFragment$NormalRequestPermissionFragment.onRequestPermissionsResult(PermissionRequestFragment.kt:53)
        at androidx.fragment.app.FragmentManager$9.onActivityResult(FragmentManager.java:2679)
        at androidx.fragment.app.FragmentManager$9.onActivityResult(FragmentManager.java:2651)
        at androidx.activity.result.ActivityResultRegistry.doDispatch(ActivityResultRegistry.java:392)
        at androidx.activity.result.ActivityResultRegistry.dispatchResult(ActivityResultRegistry.java:351)
        at androidx.activity.ComponentActivity.onRequestPermissionsResult(ComponentActivity.java:667)
        at androidx.fragment.app.FragmentActivity.onRequestPermissionsResult(FragmentActivity.java:612)
        at android.app.Activity.dispatchRequestPermissionsResult(Activity.java:7608)
        at android.app.Activity.dispatchActivityResult(Activity.java:7458)
        at android.app.ActivityThread.deliverResults(ActivityThread.java:4353)
        at android.app.ActivityThread.handleSendResult(ActivityThread.java:4402) 
        at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:49) 
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808) 
        at android.os.Handler.dispatchMessage(Handler.java:106) 
        at android.os.Looper.loop(Looper.java:193) 
        at android.app.ActivityThread.main(ActivityThread.java:6669) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

GIF with the above procedure

Expected

Actual

Environment

Hypothesis for the cause of the crash

omtians9425 commented 2 years ago

@hotchemi I'd appreciate it if you could take a look when you have time (There is no rush) 🙇

nguyennh-0786 commented 2 years ago

@hotchemi how about this PR?

ColorfulHorse commented 2 years ago

@hotchemi I'd appreciate it if you could take a look when you have time (There is no rush) 🙇

maybe lifecycleOwner = this is not always right,fragment lifecycle is different from fragment viewLifecycle

Oussemahlel commented 2 years ago

I have the same problem, any solution for this bug!!!