my app crashes when it comes back to foreground after some time playing with others applications and I can't find out how to fix it.
My app has a splash screen activity where it loads some data from web services and put it in global static variables declared in a class extending Application, as explained in this SO question. Once all data are loaded, this activity launches a Home activity with some menu to navigate in the app. The global vars are used in most activities.
At some point, while playing with other apps, it seems that my app is killed, because I can see this in the logcat:
I/ActivityManager( 2465): Process com.mysite.myapp (pid 23538) has died.
I/WindowManager( 2465): WIN DEATH: Window{4852a678 com.mysite.myapp/com.mysite.myapp.Home paused=false}
I/WindowManager( 2465): WIN DEATH: Window{485b63a8 com.mysite.myapp/com.mysite.myapp.Home paused=false}
I/WindowManager( 2465): WIN DEATH: Window{4826fbf8 com.mysite.myapp/com.mysite.myapp.ItemList paused=false}
I/WindowManager( 2465): WIN DEATH: Window{48286f90 com.mysite.myapp/com.mysite.myapp.ItemDetail paused=false}
W/GpsLocationProvider( 2465): Unneeded remove listener for uid 1000
D/GpsLocationProvider( 2465): stopNavigating
D/gps_BRCM( 2465): [status check] on_stop() : GPS_STATUS_SESSION_END
D/gps_BRCM( 2465): gps_engine_status_update 2
D/GpsLocationProvider( 2465): send an intent to notify that the GPS has been enabled or disabled
D/gps_BRCM( 2465): gps_stop: called
V/GpsLocationProvider( 2465): hybridGpsSensorDeregister : No registered sensorManager
D/GpsLocationProvider( 2465): hybridGpsSensorDeregister
and the debugger is detached.
Now, when I open my app again, the latest activity is started if it does not use global vars (in that case it crashes as soon as I navigate to an activity which does), or crashes immediately if it does.
If my app was killed, which seems to be the case because even my location service is stopped, as seen in the logcat, why does it open the latest activity instead of launching again from the splash screen?
When android kills your application, it is doing so only to save resources. In order to have a better usability, the OS will remember where you were inside that app (saving things like the activity stack a instance state if you implement the proper listeners).
When you restore your app, it will restore the activities and everything else. As you were saving data to global static variables, these might have been "lost" when the application was terminated!
I suggest you to use databases or at least check if the data is still there before using it (for example:
MyClassHolder.myGlobalStaticParameter == null
)This is not direct answer to you question, but I thought it might be useful.
Your decision to store data in global variables is bad. That's because your app can be killed each time user navigates away from it. And when he or she comes back you'll need to load data all over again.
You should use
ContentProvider
andService
.Service
should load data from internet and store it toContentProvider
.ContentProvider
should persist data. All activities should useContentProvider
to access this cached data.This way your application:
ContentProvider
is persisted across application runs (if you use SQLite for example).Of cause you need to invest some time into implementing
Service
andContentProvider
, and proper handling inAcitivities
. But your application will be more robust and scalable (you can easily add new components).A dirty workaround to your problem is to check if the global variables are filled in the onResume method of your activities. If the variables are not filled start the splashscreen activity with an Intent with the CLEAR_TOP flag set. This should cause all your activities to be removed from the activity stack and your splash screen will load and is able to reload all the data needed for your app to work.
This is a dirty workaround to help a badly designed application to work. If you want your app to be nicer to you and the user go with the solution inazaruk provided. He is correct about the basic setup of an application.