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 >> >