[ 
https://issues.apache.org/jira/browse/CB-8917?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14979024#comment-14979024
 ] 

ASF GitHub Bot commented on CB-8917:
------------------------------------

GitHub user riknoll opened a pull request:

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

    API for saving/restoring plugin and js state

    Here is my proposal for dealing with Activity destruction in Android. The 
code is still a little rough and might need to be finalized, but I wanted to 
present it for discussion. 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 as well as the js, allowing them to 
save state and have it restored if necessary.
    
    ### Saving js state
    The js is given the ability to save its state in JSON using a new method in 
`navigator.app` as part of the CoreAndroid API. An application can pass an 
object to `navigator.app.saveState()` to save state in case of Activity 
destruction. This state is returned to the js as part of the resume event's 
payload and the js application can use it to properly restore the app. The idea 
is that app developers can take care of state by subscribing to the pause event 
to save and have it returned in the corresponding resume event. Plugins are 
also given the opportunity to add to the JSON to convey any information that is 
needed for the js to resume properly (see [1] below).
    
    ### Saving plugin state
    A plugin that calls out to an external Activity is given the chance to 
properly restore its state before handling the result of the Activity by 
implementing the new `onSaveInstanceState()` and `onRestoreInstanceState()` 
methods that are called as part of the Activity lifecycle. The plugin is given 
a replacement CallbackContext as part of `onRestoreInstanceState` that can 
accept the result and add it to the resume event payload for use in the js 
(again, see [1] below).
    
    _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 (I try to emphasize this in the 
`onRestoreInstanceState` method's javadoc). 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
    
    ### 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
    * It allows the js app to save/restore its state whereas previously the app 
would just restart with no context
    
    #### Downsides:
    
    * It still requires that app developers have platform specific code in 
their js (unless other platforms adopt this API, but I don't know if they have 
the corresponding need for it)
    * 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. I also updated the camera plugin to use this new API and the only 
necessary changes to the existing plugin code were the addition of the 
onSaveInstanceState and onRestoreInstanceState methods. I can post that code 
too if there is interest in seeing what the plugin side of this looks like
    
    
    [1] Anatomy of resume event object:
    ```
    {
        action: "resume",
        state: <state object passed to app.saveState>,
        plugins: <objects for plugins in the form {serviceName:{pluginState}, 
...}>,
        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>
        }
    }
    ```


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

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

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

    https://github.com/apache/cordova-android/pull/236.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 #236
    
----
commit 2fca689f9353ddb1058b418a26818444cace79bf
Author: riknoll <rikn...@microsoft.com>
Date:   2015-10-27T19:36:43Z

    Added support for Android lifecycle state saving/restoring

commit 02ef016863cc6faf722149342294566564f8055e
Author: riknoll <rikn...@microsoft.com>
Date:   2015-10-28T18:03:59Z

    Cleaning up the resume event object api a bit

commit 760223e076783337a8442f61237b2820f7026f1d
Author: riknoll <rikn...@microsoft.com>
Date:   2015-10-28T18:09:56Z

    Merge branch 'master' of 
https://git-wip-us.apache.org/repos/asf/cordova-android

commit 448c69555f002378f88ff06b26dc797fe2f3d5a1
Author: riknoll <rikn...@microsoft.com>
Date:   2015-10-28T18:43:15Z

    Removed logging code

----


> Add api/way to get plugins results even when Cordova activity restarts  
> ------------------------------------------------------------------------
>
>                 Key: CB-8917
>                 URL: https://issues.apache.org/jira/browse/CB-8917
>             Project: Apache Cordova
>          Issue Type: Improvement
>          Components: Android
>            Reporter: Bnaya
>
> In android when you have a plugin that opens new activity the CordovaActivity 
> will be killed and you won't get the result from the plugin.
> The new activity will get the results but because the plugin objects are dead 
> and the webview reloaded you can get the data to the js callback.
> The most noticeable example is the camera plugin. (And maybe its the same 
> with even more platforms)
> possible solution for this is to add metadata to the device ready event with 
> incoming data from plugins.



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscr...@cordova.apache.org
For additional commands, e-mail: issues-h...@cordova.apache.org

Reply via email to