When my app starts, I load all the string data coming from the server in a hashmap and all the screens read from this hashmap in order to display button names, texts and screen titles.
I count on this object (and a lot of other similar objects)'s lives to be maintained for my app to remain functional.
I have found that, if I resume the app after a few hours it is still functional. But if I open 10 more apps, leave them all open and resume the app after a few hours, it tries to read from one of these objects, but they are now gone!
In these cases, I find it best to kill the app and restart it, and tried doing so in the onDestroy of the main activity but this backfired because 5 seconds after I switch to another activity, onDestroy of the previous activity is called and the app gets killed using this code:
android.os.Process.killProcess(android.os.Process.myPid());
So I only want to kill the app when its been idle for hours AND the resources have been nullified. This way when the user tries to resume it, it will die and start again, thus loading all the resources in the memory again.
I looked for an onDestroy method in Application class but there isnt one. Thre is an onTrimMemory method.
QUESTION IS:
How do I use Application.onTrimMemory() callback to kill my application IF resources that it needs have been destroyed?
EDIT: Actually, reading the onTrimMemory documentation, Im left with the impression that its me that should release memory by destroying objects, and if I dont do so, then how come after resuming the app, these objects are now null? I dont get it.
EDIT2:
I managed to partly solve my problem:
I downloaded a "Fill Ram" app from Google made for developers who want to see how their app behaves at low memory situations
I gradually started filling ram and saw how onTrimMemory methods were called with values or respectively 20, 40, 60 and 80
after each time I saw it being called in the logs I quickly resumed my app and then at around 60 or 80, the resources I needed were null
I inserted a null pointer check in onResume and if those resources were null, I did the following:
if (application.data == null || application.data.size() == 0) {
// Restart app so data is reloaded
Log.e("kill app", "kill app");
Intent mStartActivity = new Intent(this,MainActivity.class);
int mPendingIntentId = 123456;
PendingIntent mPendingIntent = PendingIntent.getActivity(this, mPendingIntentId, mStartActivity, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager mgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, mPendingIntent);
System.exit(0);
}
as pointed out here:
how to programmatically "restart" android app?
The problem remains semi-resolved, because I suppose at some other place in my app some other resource might go missing, so I am considering doing this in onTrimMemory 60 or 80?
I need some more help in understanding this.
Also, should I use
System.exit(0);
or
android.os.Process.killProcess(android.os.Process.myPid());
I did something else in addition:
in my base activity that all other activities extend, I added the following:
@Override
public void onTrimMemory(int level) {
super.onTrimMemory(level);
if (level > TRIM_MEMORY_MODERATE) {
// Restart app so data is reloaded
android.os.Process.killProcess(android.os.Process.myPid());
}
}