cordova-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Jesse <purplecabb...@gmail.com>
Subject Re: Android plugin crash on resume when activity destroyed
Date Fri, 05 Jun 2015 00:52:32 GMT
I'm off for a week after tomorrow, so 2 weeks?
I'll try to get a discuss thread up tomorrow.

@purplecabbage
risingj.com

On Thu, Jun 4, 2015 at 3:00 PM, Serge Huijben <s.huijben@gmail.com> wrote:

> Sounds great Jesse, it would be awesome to have some context awareness in a
> startup event.
> any idea when you could have this ready?
>
> - Serge
>
> Op do 4 jun. 2015 om 22:52 schreef Jesse <purplecabbage@gmail.com>:
>
> > Yes, I am working on a unified solution, which is to include a
> > pre-deviceready event which contains launch context data.  This
> would/could
> > include being launched from an intent, or a url:protocol that you have
> > registered, a local notification, a push notification, launch from a
> > secondary tile, ....
> >
> > Typically an app that needs to maintain state should do it whenever state
> > changes.  pause/resume events can be used as well, but there is no
> specific
> > event for going from paused->destroyed other than possibly being able to
> > use window.onunload | addEventListener('unload'..
> >
> >
> >
> >
> > @purplecabbage
> > risingj.com
> >
> > On Thu, Jun 4, 2015 at 1:04 PM, Dan Polivy <dan@cellartracker.com>
> wrote:
> >
> > > 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.huijben@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.huijben@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 <dan@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: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
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message