cordova-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Dan Polivy <...@cellartracker.com>
Subject RE: Android plugin crash on resume when activity destroyed
Date Wed, 03 Jun 2015 21:30:46 GMT
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:bowserj@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. <ommenjik@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.huijben@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 <dan@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-unsubscribe@cordova.apache.org
For additional commands, e-mail: dev-help@cordova.apache.org
Mime
View raw message