Is there any notification to the app via JS that the activity is being 
destroyed, e.g. to allow the app to save state?

FWIW, I think any plugin that invokes another intent that returns data is 
potentially vulnerable to this issue --  e.g. barcode scanner being another one 
(I have a few real world crashes on this, too -- but not as many as for 
Camera). So a more general purpose solution might be appropriate if possible.

Dan

-----Original Message-----
From: Serge Huijben [mailto:s.huij...@gmail.com] 
Sent: Wednesday, June 03, 2015 11:39 PM
To: dev@cordova.apache.org
Subject: Re: Android plugin crash on resume when activity destroyed

Joe, it failing on Travis was not caused by the code in the pullrequest.
I just changed one word in the readme.md and committed that to have Travis
build it again and now it's all good.

- Serge

Op do 4 jun. 2015 om 07:54 schreef Serge Huijben <s.huij...@gmail.com>:

> I must say that restoring state in the webview has not been a problem for
> me. admittedly our app is only for Android 4.1 (sdk 16) and higher.
> In our app we save state all the time using localstorage, and I do know
> exaxtly where the user was at --> he was taking a picture or selecting one
> from the gallery
> that leaves me with only one possible view to deliver to the user.
> I just call checkForSavedResult on the camera plugin in onDeviceReady
> using a promise and if it returns a value I take the user to that view.
> localstorage is still intact so the user is non the wiser, maybe only a bit
> confused as to why he just saw the splashscreen. if the returnvalue is an
> empty string I take the user to the "welcome" view
>
> This method could be generalised but as Joe pointed out, there's little
> chance of this occurring in plugins other than the camera plugin.
>
> - Serge
>
>
> Op wo 3 jun. 2015 om 23:31 schreef Dan Polivy <d...@cellartracker.com>:
>
>> Interesting, thanks for the history, Joe and Serge.
>>
>> I do probably agree with you, Joe, that this won't work well as it'll be
>> hard to restore the DOM to the correct state. I can say that for my app,
>> it's pretty unlikely to get exactly back to where you started. In prior
>> versions of Cordova (pre-4.0), I think that instead of a crash, the user
>> experience was the app just appeared to restart itself.
>>
>> At the very least, is there any possibility of better handling this
>> scenario at a general level so it doesn't lead to a crash? I guess a
>> targeted fix for the Camera plugin, to perhaps detect this and throw an
>> error dialog, might be a start. I've also seen this with the barcode
>> scanner plugin (which uses the camera). I don't know the policy on
>> introducing localized strings in the core platform components, but if
>> there's a way to handle that, it seems like showing the user a (native)
>> notification that it failed would be appropriate.
>>
>> It may also be prudent to update the plugin development guide to discuss
>> this issue and how to prevent crashes from referencing uninitialized
>> instance variables in the intent callback.
>>
>> I may also play with Serge's solution and see if it is viable, and will
>> report back what I find.
>>
>> Dan
>>
>> -----Original Message-----
>> From: Joe Bowser [mailto:bows...@gmail.com]
>> Sent: Wednesday, June 03, 2015 11:44 AM
>> To: dev@cordova.apache.org
>> Subject: Re: Android plugin crash on resume when activity destroyed
>>
>> This has been a problem since we started, and there's no solution to it
>> because there's no reliable way to restore state on a WebView.  We have
>> tried in the past, and failed miserably.  I'm extremely skeptical that
>> this
>> would even work, since this apparently failed Travis.  That said, if it
>> does, every intent would have to manage their own state, and even when the
>> plugin is loaded, we still don't know where in the app the user would be
>> at, so returning a photo to a part of the DOM that doesn't even exist
>> would
>> have JS errors.
>>
>> Of course, this only happens when you're using a LOT of memory, like what
>> Cameras tend to do, and other Intents, like for example, requesting
>> permission to use a Tango Service on a Project Tango plugin, (
>> https://github.com/infil00p/PhoneGapTango) or other third party plugins
>> wouldn't run into the same problems.
>>
>> This is a problem with the Android architecture, and many native apps have
>> run into similar problems.  I don't think there's a solution for this in
>> Cordova, and we have definitely tried.
>>
>> On Wed, Jun 3, 2015 at 9:46 AM Mefire O. <ommen...@microsoft.com> wrote:
>>
>> > Interesting fix, Serge. A question comes to mind:
>> > - Since it seems like this issue affects all android plugins that call
>> > other intents, won't we have to do this for all of them? Is there a way
>> we
>> > can leverage your PR and maybe come up with a general solution ? Maybe
>> fit
>> > the boilerplate code (state saving/restoring) somewhere all android
>> plugins
>> > can inherit ?
>> >
>> > On Jun 3, 2015 3:54 AM, Serge Huijben <s.huij...@gmail.com> wrote:
>> > what I did to solve this is add a check for callbackcontext, If that is
>> > null save the incoming parameters.
>> >         if (this.callbackContext == null) {
>> >             this.savedRequestCode = requestCode;
>> >             this.savedResultCode = resultCode;
>> >             this.savedIntent = intent;
>> >         } else {
>> >            // procede as planned
>> >
>> > This is what happens after the activity has been killed by the system
>> while
>> > you are in the camera Intent.
>> > Once you take or select your picture the mainactivity is restarted and
>> with
>> > it all the plugins, after which onActivityResult is fired.
>> >
>> > the code above saves the incoming parameters so they can be used later.
>> > To do this I also added a new method, checkForSavedResults, specially
>> for
>> > Android, you call this method in your onDeviceReady javascript method
>> that
>> > will fire once the activity is restarted, and this will give you the
>> > previously taken or selected picture.
>> >
>> > I put this in a pullrequest
>> > https://github.com/apache/cordova-plugin-camera/pull/97
>> > It solves Issue CB-8804 https://issues.apache.org/jira/browse/CB-8804
>> >
>> > hope this helps,
>> >
>> > Serge
>> >
>> >
>> > Op di 2 jun. 2015 om 21:06 schreef Dan Polivy <d...@cellartracker.com>:
>> >
>> > > On Android, when using plugins that launch other intents, e.g. the
>> Camera
>> > > plugin, I'm now seeing reliable crashes when the cordova activity is
>> > > resumed - if it was "destroyed" when the intent launched. The reliable
>> > way
>> > > to reproduce this is to enable the "Don't keep activities" setting in
>> > > Android's Developer options. Based on the Google Play crash reports,
>> this
>> > > just started when we updated our app to use the new
>> cordova-android@4.0.0
>> > > <mailto:cordova-android@4.0.0> runtime.
>> > >
>> > > In the Camera plugin, the issue is that the
>> > > CameraLauncher.processResultFromCamera method uses an instance
>> variable,
>> > > imageUri, which is set prior to launching the intent, but null when
>> the
>> > > activity is resumed. Presumably, this is because the plugin isn't
>> aware
>> > > that it needs to save state? Here's the full stack trace:
>> > >
>> > > java.lang.RuntimeException: Unable to resume activity {<app>}:
>> > > java.lang.RuntimeException: Failure delivering result
>> > ResultInfo{who=null,
>> > > request=34, result=-1, data=null} to activity {<app>}:
>> > > java.lang.NullPointerException: Attempt to invoke virtual method
>> > > 'java.lang.String android.net.Uri.toString()' on a null object
>> reference
>> > > at
>> > >
>> >
>> android.app.ActivityThread.performResumeActivity(ActivityThread.java:3349)
>> > > at
>> > >
>> android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3380)
>> > > at
>> > >
>> android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2731)
>> > > at android.app.ActivityThread.access$900(ActivityThread.java:172)
>> > > at
>> android.app.ActivityThread$H.handleMessage(ActivityThread.java:1421)
>> > > at android.os.Handler.dispatchMessage(Handler.java:102)
>> > > at android.os.Looper.loop(Looper.java:145)
>> > > at android.app.ActivityThread.main(ActivityThread.java:5835)
>> > > at java.lang.reflect.Method.invoke(Native Method)
>> > > at java.lang.reflect.Method.invoke(Method.java:372)
>> > > at
>> > >
>> >
>> com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1388)
>> > > at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1183)
>> > > Caused by: java.lang.RuntimeException: Failure delivering result
>> > > ResultInfo{who=null, request=34, result=-1, data=null} to activity
>> > {<app>}:
>> > > java.lang.NullPointerException: Attempt to invoke virtual method
>> > > 'java.lang.String android.net.Uri.toString()' on a null object
>> reference
>> > > at android.app.ActivityThread.deliverResults(ActivityThread.java:3977)
>> > > at
>> > >
>> >
>> android.app.ActivityThread.performResumeActivity(ActivityThread.java:3335)
>> > > ... 11 more
>> > > Caused by: java.lang.NullPointerException: Attempt to invoke virtual
>> > > method 'java.lang.String android.net.Uri.toString()' on a null object
>> > > reference
>> > > at
>> > >
>> >
>> org.apache.cordova.camera.CameraLauncher.processResultFromCamera(CameraLauncher.java:445)
>> > > at
>> > >
>> >
>> org.apache.cordova.camera.CameraLauncher.onActivityResult(CameraLauncher.java:674)
>> > > at
>> > >
>> >
>> org.apache.cordova.CordovaInterfaceImpl.onActivityResult(CordovaInterfaceImpl.java:120)
>> > > at
>> > >
>> >
>> org.apache.cordova.CordovaActivity.onActivityResult(CordovaActivity.java:321)
>> > > at android.app.Activity.dispatchActivityResult(Activity.java:6475)
>> > > at android.app.ActivityThread.deliverResults(ActivityThread.java:3973)
>> > > ... 12 more
>> > >
>> > > I've been looking at this for a bit, and am wondering whether this can
>> > > even be supported with the current plugin architecture. I see that
>> > onStart
>> > > and onStop are now part of the plugin interface, but not
>> > > onSaveInstanceState/onRestoreInstanceState. It seems like a fairly
>> common
>> > > pattern for plugins to save the CallbackContext, so this will impact
>> more
>> > > than just the Camera plugin.
>> > >
>> > > Has any thought gone into supporting this scenario? Is it possible to
>> do
>> > > with the current plugin interface, or would it need to be extended to
>> add
>> > > the instance state handlers to allow plugins to preserve necessary
>> state?
>> > > I'm happy to take a stab at addressing this, but would appreciate
>> insight
>> > > from the android native devs on the right way to approach this issue.
>> (I
>> > > haven't yet filed a JIRA issue on this, but will shortly.)
>> > >
>> > > Thanks,
>> > > Dan
>> > >
>> > >
>> > >
>> >
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscr...@cordova.apache.org
>> For additional commands, e-mail: dev-h...@cordova.apache.org
>>
>

Reply via email to