fondesa / kpermissions

A Kotlin library which helps to request runtime permissions in Android.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Is there a way to automatically store and restore anonymous listener?

zhombie opened this issue · comments

It would be great if there is a way to hold listener on configuration change (maybe orientation change) and dispatch event after restoration, also destroy itself after dispatch. Default setListener(context) with PermissionRequest.Listener implementation works as expected, but extension function send { result -> } sets anonymous object as listener, which is killed on configuration change and there is no events on result

Someone locks orientation change feature on permission request and restores after request is finished, but i don't think that is good for UX. Also, it just handles orientation change, there are many more events that could change configuration

https://github.com/ssseasonnn/PermissionX/blob/master/permissionx/src/main/java/zlc/season/permissionx/Util.kt

Screenshot 2021-12-19 at 16 27 27

Unfortunately this is impossible due to Android's limitations.
The problem is not the extension function itself but where you call it.
This library can't "save" the instance of your listeners, anonymous or not, otherwise it would create memory leaks. It works with addListener() only because you are probably calling it in a lifecycle event which is invoked always after the state is saved and restored (e.g. onCreate()) so the library can attach the new instance of the listener to the request.

Let me explain it with an example.

This is the "working version" that you are talking about:

override fun onCreate(savedInstanceState: Bundle?) {
    // The value of "this" changes after a configuration change since the activity instance changes, the library adds the listener to the request.
    request.addListener(this)
    button.setOnClickListener {
        request.send()
    }
}

This instead is the "non-working" one:

override fun onCreate(savedInstanceState: Bundle?) {
    button.setOnClickListener {
        // The anonymous instance of the listener is created and attached ONLY when the button is clicked, so, after the configuration change, you are not clicking the button again so there are no listeners to notify.
        request.send { }
    }
}

The "non-working" one is the same as this one, it's not the same as the working one conceptually:

override fun onCreate(savedInstanceState: Bundle?) {
    button.setOnClickListener {
        request.addListener(this)
        request.send()
    }
}

Even if this library would lock the orientation change, the process can be killed and restored or another configuration change would happen. Furthermore I do not like at all to implement some hacky workaround which impacts the users of this library in a negative way (e.g. locking the orientation, creating memory leaks) so I'd implement only safe solutions, and unfortunately, I don't know any of them for this case.

I hope the answer was clear, feel free to re-open the issue if you have some doubts.