cordova-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From riknoll <...@git.apache.org>
Subject [GitHub] cordova-android pull request: CB-8917: Added pending plugin callba...
Date Wed, 11 Nov 2015 01:05:01 GMT
GitHub user riknoll opened a pull request:

    https://github.com/apache/cordova-android/pull/239

    CB-8917: Added pending plugin callbacks to resume event payload

    This is a redo of #236 after receiving some feedback. This relates to CB-8917 and CB-9189.
    
    ### Background
    The issue at hand is that plugins can make calls to an external Activity and, if the device
is low on memory, there is a chance that the CordovaActivity will get killed in the background
causing the plugin to lose its state as well as its context for the callback. Activities in
Android typically handle this situation by using `onSaveInstanceState()` and `onCreate()`
methods to save and restore state respectively as the Activity is created and destroyed. This
solution exposes that lifecycle to plugins, allowing them to save state and have it restored
if necessary.
    
    ### Saving/Restoring plugin state
    Two new methods are exposed to plugins that they can override to save/restore state.
    ```java
    /**
     * Called when the Activity is being destroyed (e.g. if a plugin calls out to an external
     * Activity and the OS kills the CordovaActivity in the background). The plugin should
save its
     * state in this method only if it is awaiting the result of an external Activity and
needs
     * to preserve some information so as to handle that result; onRestoreStateForActivityResult()
     * will only be called if the plugin is the recipient of an Activity result
     *
     * @return  Bundle containing the state of the plugin or null if state does not need to
be saved
     */
    public Bundle onSaveInstanceState() {}
    
    /**
     * Called when a plugin is the recipient of an Activity result after the CordovaActivity
has
     * been destroyed. The Bundle will be the same as the one the plugin returned in
     * onSaveInstanceState()
     *
     * @param state             Bundle containing the state of the plugin
     * @param callbackContext   Replacement Context to return the plugin result to
     */
    public void onRestoreStateForActivityResult(Bundle state, CallbackContext callbackContext)
{}
    ```
    The plugin is given a replacement CallbackContext as part of `onRestoreStateForActivityResult`
that can accept the result the plugin would normally return and add it to the resume event
payload for use in the js (see JSON below). Thus, it requires minimal modifications to existing
plugins
    
    _NOTE:_ When I mention that plugins are given the opportunity to restore state, I want
to clarify that this only happens for plugins that are waiting for an external Activity result.
This makes the API a little less intuitive, but otherwise we would be conflicting with the
accepted behavior that plugins currently get destroyed (i.e. lose all of their state) and
are selectively rebuilt whenever a new URL is loaded into the webview. If we restore state
on resume, then we can end up with some awkward cases where part of the resuming involves
loading a new page so the state gets lost again and so on and so forth. My thinking is that
restoring the other state is better left to app developers
    
    ### Saving/Restoring js state
    We already send out pause and resume events. This solution enhances these events in the
case of Activity destruction by adding to them the result of any pending Plugin calls. The
resume event is of the form
    ```
    {
        action: "resume",
        pendingResult: {
            pluginServiceName: <plugin service name e.g. "Camera">,
            pluginStatus: <description of result' status (see PluginResult.java)>,
            result: <argument(s) that would have been given to the callback>
        }
    }
    ```
    It is the responsibility of the application developer to properly use these events and
save their state as well as keep information about what plugin results they have pending.
We should provide guidance for this in the Android documentation and plugin documentation
should clearly communicate when it is necessary.
    
    ### Discussion
    #### Benefits:
    
    * It requires minimal updates to existing plugins (and no updates at all if the plugin
doesn't use an external Activity)
    * It is a general solution/pattern that plugins can follow rather than forcing them to
include platform specific methods in their APIs
    
    #### Downsides:
    
    * The resume callback will only ever get received after the initial page loads (potential
page flickering)
    * The pending result part of the event object doesn't provide much context (so it puts
more responsibility on the app developer to keep state so they know what they're getting)
    
    In the core plugins, this is mostly relevant to the Camera plugin which previously would
crash upon receiving the Activity result if the CordovaActivity had been killed by the OS
while a picture was being taken/chosen (CB-9189). The updated Camera Plugin can be found in
[this branch](https://github.com/MSOpenTech/cordova-plugin-camera/tree/save-state-plugin-only)
and a (trivial) example application that uses this API + instructions for testing can be found
[here](https://gist.github.com/riknoll/d0ab25583b1dc8ab22af).


You can merge this pull request into a Git repository by running:

    $ git pull https://github.com/MSOpenTech/cordova-android save-state-plugin-only

Alternatively you can review and apply these changes as the patch at:

    https://github.com/apache/cordova-android/pull/239.patch

To close this pull request, make a commit to your master/trunk branch
with (at least) the following in the commit message:

    This closes #239
    
----
commit 62a7873792205696c25b8498b521ef9828648e59
Author: riknoll <richard.b.knoll@gmail.com>
Date:   2015-11-10T23:01:13Z

    CB-8917: Added pending plugin callbacks to resume event payload

----


---
If your project is set up for it, you can reply to this email and have your
reply appear on GitHub as well. If your project does not have this feature
enabled and wishes so, or if the feature is enabled but not working, please
contact infrastructure at infrastructure@apache.org or file a JIRA ticket
with INFRA.
---

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@cordova.apache.org
For additional commands, e-mail: dev-help@cordova.apache.org


Mime
View raw message