You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* This creates a problem: some permission request frameworks use a transparent `Fragment` to get permission request callbacks. If the permission request framework uses `android.support.v4.app.Fragment`, then it must require the outer layer to pass in an `android.support.v4.app.FragmentActivity` object. If the `Activity` you're using is not a subclass of `android.support.v4.app.FragmentActivity`, what should you do? Simple, you might say, just modify the current `Activity` to directly inherit from `android.support.v4.app.FragmentActivity`, right? But what if your current `Activity` must inherit from `FlutterActivity`, `ComposeActivity`, `UnityPlayerActivity`, or `Cocos2dxActivity`? What should you do then? Modify their source code? Or modify the permission framework's source code? Whichever solution you choose, the cost of adaptation will be very high and difficult to maintain in the future. This is neither realistic nor scientific. Do you suddenly feel like heaven has blocked your path? Is writing permission request API code by hand the only way to implement permission requests?
201
+
* This creates a problem: some permission request frameworks use a transparent `Fragment` to get permission request callbacks. If the permission request framework uses `androidx.fragment.app.Fragment`, then it must require the outer layer to pass in an `androidx.fragment.app.FragmentActivity` object. If the `Activity` you're using is not a subclass of `androidx.fragment.app.FragmentActivity`, what should you do? Simple, you might say, just modify the current `Activity` to directly inherit from `androidx.fragment.app.FragmentActivity`, right? But what if your current `Activity` must inherit from `FlutterActivity`, `ComposeActivity`, `UnityPlayerActivity`, or `Cocos2dxActivity`? What should you do then? Modify their source code? Or modify the permission framework's source code? Whichever solution you choose, the cost of adaptation will be very high and difficult to maintain in the future. This is neither realistic nor scientific. Do you suddenly feel like heaven has blocked your path? Is writing permission request API code by hand the only way to implement permission requests?
202
202
203
-
* Actually, the framework has already thought of this problem and has solved it for you without requiring any handling on your part. The specific implementation principle is: the framework will determine if the `Activity` object you pass in is a subclass of `android.support.v4.app.FragmentActivity`. If it is, it will use `android.support.v4.app.Fragment` for permission requests; if not, it will use `android.app.Fragment` for permission requests. This way, no matter which type of `Activity` you use, the framework can automatically adapt.
203
+
* Actually, the framework has already thought of this problem and has solved it for you without requiring any handling on your part. The specific implementation principle is: the framework will determine if the `Activity` object you pass in is a subclass of `androidx.fragment.app.FragmentActivity`. If it is, it will use `androidx.fragment.app.Fragment` for permission requests; if not, it will use `android.app.Fragment` for permission requests. This way, no matter which type of `Activity` you use, the framework can automatically adapt.
204
204
205
205
#### Callback Lifecycle Synchronized with Host
206
206
207
-
* Most permission request frameworks on the market use a single type of `Fragment` to handle permission request callbacks, but this leads to a problem. Suppose a framework uses `android.support.v4.app.Fragment` to handle permission request callbacks, but you initiated the permission request in `android.app.Fragment`, or vice versa, you used `android.support.v4.app.Fragment` but the framework used `android.app.Fragment`. You can't pass your own `Fragment` as the host to the permission request framework; you can only pass the `Activity` object to the framework through `fragment.getActivity()`. This makes the `Activity` the host object, leading to a lifecycle asynchronization problem: your own `Fragment` may have been destroyed, but the framework will still callback the permission request result listener, causing `Memory leak` at best and triggering `Exception` at worst.
207
+
* Most permission request frameworks on the market use a single type of `Fragment` to handle permission request callbacks, but this leads to a problem. Suppose a framework uses `androidx.fragment.app.Fragment` to handle permission request callbacks, but you initiated the permission request in `android.app.Fragment`, or vice versa, you used `androidx.fragment.app.Fragment` but the framework used `android.app.Fragment`. You can't pass your own `Fragment` as the host to the permission request framework; you can only pass the `Activity` object to the framework through `fragment.getActivity()`. This makes the `Activity` the host object, leading to a lifecycle asynchronization problem: your own `Fragment` may have been destroyed, but the framework will still callback the permission request result listener, causing `Memory leak` at best and triggering `Exception` at worst.
208
208
209
209
* The reason for this problem is that the `Fragment` used by the third-party framework and your `Fragment` are not actually the same type. Although they have the same class name, they are in different packages. Plus, as just mentioned, you can only pass the `Activity` object to the framework through `fragment.getActivity()`, so your own `Fragment` cannot form an effective lifecycle binding with the framework's `Fragment`. What you actually want is to bind to your own `Fragment`'s lifecycle, but the framework ultimately binds to the `Activity`'s lifecycle, which can easily trigger a crash. You can see the specific manifestation in this issue: [XXPermissions/issues/365](https://github.com/getActivity/XXPermissions/issues/365).
210
210
211
-
* Actually, the framework has already thought of this problem and has solved it for you without requiring any handling on your part. The approach to solving this problem is: the framework will automatically select the best type of `Fragment` based on the type of object you pass in. If the host you pass in is an `android.support.v4.app.FragmentActivity` or `android.support.v4.app.Fragment` object, the framework will internally create an `android.support.v4.app.Fragment` to receive permission request callbacks. If the host you pass in is a regular `Activity` or `android.app.Fragment`, the framework will internally create an `android.app.Fragment` to receive permission request callbacks. This way, no matter what host object you pass in, the framework will bind to its lifecycle, ensuring that when the permission request result is called back to the outermost layer, the host object is still in a normal state.
211
+
* Actually, the framework has already thought of this problem and has solved it for you without requiring any handling on your part. The approach to solving this problem is: the framework will automatically select the best type of `Fragment` based on the type of object you pass in. If the host you pass in is an `androidx.fragment.app.FragmentActivity` or `androidx.fragment.app.Fragment` object, the framework will internally create an `androidx.fragment.app.Fragment` to receive permission request callbacks. If the host you pass in is a regular `Activity` or `android.app.Fragment`, the framework will internally create an `android.app.Fragment` to receive permission request callbacks. This way, no matter what host object you pass in, the framework will bind to its lifecycle, ensuring that when the permission request result is called back to the outermost layer, the host object is still in a normal state.
212
212
213
213
* At this point, you might jump in and say, I can implement this without the framework. I can manually check the `Fragment`'s state in the permission callback method. Isn't it just a matter of two or three lines of code? Why does the framework make it so complicated? Your idea seems reasonable but doesn't stand up to scrutiny. If your project requests permissions in a dozen places, you would need to consider this issue in every callback method. Additionally, when requesting new permissions in the future, you would also need to consider this issue. Can you ensure that you won't miss anything when making changes? And what if this requirement was developed by your colleague, but only you know about this issue, and they are unaware? Do you know what might happen in that case? I believe you understand better than I do. The solution you provided, although it can temporarily solve the problem, treats the symptoms but not the root cause. The fundamental issue is that the approach to solving the problem is flawed, following a patch-the-hole mentality rather than thinking about blocking the leak at the source. Or perhaps you already knew how to completely cure it but chose the easiest way to handle it, which undoubtedly plants a time bomb in the project.
0 commit comments