Android simulate temporary Activity destruction? - android

Is there a way to simulate an Activity being "temporarily" destroyed (as described in the Activity.onDestroy documentation)?
Perform any final cleanup before an activity is destroyed. This can happen either because the activity is finishing (someone called finish() on it, or because the system is temporarily destroying this instance of the activity to save space. You can distinguish between these two scenarios with the isFinishing() method.
It appears this is happening to my App on some devices. After the "temporary" onDestroy, the Activity gets later gets an onResume, which isn't handled properly by my code (and, I would like to test and correct this).

In Developer Options in the phone's settings, near the bottom of the list, you can turn on "Don't keep Activities". When you press the home button, the system will destroy your Activity sort-of mimicking a low-memory situation. When you re-open your application, your activity will be re-created with a savedInstanceState bundle.
To enable Developer Options, go to 'Settings -> About phone' and click on the Build number 7 times quickly.
Edit: if this doesn't reproduce your problem, you can also try force-closing your app from ddms and re-opening it. This should work too.

Related

How to force Android to trigger activity kill

I am having an issue that's closely related to
support FragmentPagerAdapter holds reference to old fragments
and ViewPager and fragments — what's the right way to store fragment's state?
Anyway, my problem is that my application crashes on this one activity when it gets recreated after the system kills it. As it's a pretty heavy activity and I'm debugging to implement fixes, I need to trigger the "Activity killed by android system".
Right now, I am doing "Open 20 other apps, and then hope that my app gets killed before reopening it".
Is there any better way?
PS: I have tried killing it manually (force killing) from app information. It doesn't work, as my application gets recreated from my home screen
Actually I found an answer...
In developers settings, all the way down, look for
App -> Do not keep activities
Tick it, then launch your activity, leave it using homescreen, launch any other app (gallery or whatever), and then when you relaunch your app, it will have been killed by the android system
Calling the finish() method should work.
If you are inside of the context of the activity then simply call finish();
If you are outside of the context. Then pass the context of the activity and call
activity.finish();

Prevent activity from being destroyed as long as possible

I have an app, a single activity app with fragments in it.
The usual use case for this app is, that you start it and put the phone away and every now and then, you get back to the phone and insert some data... It's a logging app, you are doing something and insert your results into the app...
I have the problem, that every now and then, my activity get's destroyed and is recreated with an empty bundle... (Most of the time this is not the case, but every now and then this happens...). My app sometimes starts a service, even this service is killed in this case...
This means, that the system has killed my app, does it? How can I avoid this?
I need to keep the user data and the current top fragments... And they are saved to the bundle and everything works as long as their states and the data get saved...
Btw., my activity is always the TOP ACTIVITY, only that the screen turns off often... I just want to keep my activity alive as long as possible until the user leaves it with the back button... Or to save the state reliably
IMPORTANT NOTE
onSaveInstance does not always work (it's not part of the lifecycle and therefore not guaranteed to be called)... it only works most of the time... I need a way to that works always... If android kills my app...
don't keep your app in memory
You don't want to block Android from killing your app. What you want is to restore your app's state properly. Then the user will never notice the app has been destroyed and the user still gets the benefit of an app that was destroyed when not in use.
If you really want this use a wakelock. This will drain your users battery so I think twice before implementing this... Info at How do I prevent an Android device from going to sleep programmatically?
onSaveInstanceState explained
To do so check what information is needed in the bundle and persist that information with the onSaveInstanceState(bundle:Bundle) method so you can reuse it in onCreate(sameBundle:Bundle).
More information available from Google documentation at Save your Activity state and Restore your Activity State.
About Android Activity lifecycle
As stated by #prom85 in the comments below it's not guaranteed that the onSaveInstanceState method will be called because it's not part of the lifecycle. Workaround for this is using the onPause lifecycle hook to ensure your data is stored.
More information at Android: onSaveInstanceState not being called from activity
I had a similar problem, I arrived at this post while searching for a solution, you have to play with the manifest to achieve this and also understand what exactly activity is, in Android eco system,
In Android activity is a task which has a pre defined work.
I dig a lot in the documentation, I found that, we can configure activity in two ways,
Persistent
non persistent
if you mention for the activity in the manifest as
android:persistent="true"
and run the below use case
Start the APP
Press back or home button
you select the activity in the back stack again to bring it to front
Activity enters start -> pause -> stop - > resume , it does not get into onDestroy method.
if do not mention
android:persistent="true"
for the same use case
Activity enters start -> pause -> stop -> destroy, and if you select the activity from the back stack
Activity enters resume->create->start
If you want to run a service/task on activity start which keeps running when the app is in back stack, then you have to start that in the onCreate method, and kill them onDestroy by specifying your activity as persistent in manifest.
I hope my above solution might help others who arrive here for the same problem

pressing home button and access app again from app icon call onCreate?

I have an offline-online application, i found a strange issue in it, may be it is not, but i did'nt understand about it..
App requirement is that, if internet is available, even from starting app or from resuming, i call webservices and store data in sqlite, otherwise app stays in offline mode,
I have 2 activities, second activity contains an id, that i passes through intent (that point is important),
My Problem:
if i am in second activity, and internet is running, and i press home button , then this 2nd activity pauses, then stop which is a default behavior in android, i goto settings, turn wifi off, then press app icon again to get back in my app, here i got confused, i expect that my app now will be in onResume, but when i see in logcat its onCreated called and app
crashes, nullPointerException occurs, because this 2nd activity does not have that id, i passed through intent..
Note:
If i use recent app button to go to "settings", then come back again after turing wifi off, and repeat all this behavior, then working fine, its onResumes called not oncreate..
My Question
Why it is going in onCreate while i my expectation is to be onResume while i came back from app icon?
The NPE reason is clear, your second activity doesn't have the value and it crashes.
Why do you get different behavior then!?
It's because the launching intents are different. When you "task switch" Android is merely stopping your app but leaving it there (no guarantee) in case you want to switch back.
Going home (with home) is a clear indication that you want to leave the app, and although it will remain in memory and cached (as long as there is available memory), going back through the launcher (or App Icon as you call it) fires the LAUNCHER category (which goes to your Activity 1 first).
Take a look at this StackOverflow question (and answer) to better understand the consequences.
In any case, your problem is that your app must always be designed to resume in an inconsistent state and be able to recover. Android will kill your references, will destroy your variables and most likely send your app to hell overnight even if you have it running… if the phone goes on standby, chances are processes that aren't doing anything will be paused/stopped and likely killed.
Re-design your app so this is not a problem.
You say:
"I have 2 activities, second activity contains an id, that i passes
through intent (that point is important),"
Well, why not make it easier and have ONE activity and TWO fragments? Then use Fragment Arguments to pass the value?
Or why not store the value in the preferences and/or a local database and recover it during onCreate?
And also why not make it so that if Activity 2 doesn't have a value, it calls Activity 1 and closes itself (better than a crash, huh?).
Etc.
As you can see there are multiple things you should consider. All in all, never trust that your app will be alive, because it won't.
Once your activity's onStop gets called it's susceptible to be killed by the android system to collect resources for other apps which is what i think happened in your case.If it is killed, android will obviously call OnCreate when you get back to the activity.Check this for clarification. For experimenting you can try opening more than one apps from your recent apps and then return to your app. It may crash there too now.
You stated that you can see that the activitiy is stopped (onStop) if you go to the settings. That is the behaviour shown in the Android activity lifecycle. The counterpart for onStop is onCreate. So it does what the documentation tells us. Btw activities are paused if they are visible in some way and get stopped if they are not visible anymore. This would explain why your activity get paused. For further information read Managing the Activity Lifecycle. You can find a whole picture of the lifecycle here.
This type of behaviour can be seen when you change some system configurations like font type,font size or language. But turning wifi on/off won't destroy the app and recreate it again. Check http://developer.android.com/guide/topics/manifest/activity-element.html#config for more information

Getting a call Vs pressing home

I run my android app, and when I press home button and come back to the app. Everything is maintained (the score, the state ..etc). assume it goes to OnPause the OnResume.
However, when I get a phone call while running my app, then my app state is reset (score is gone ..etc).
Why is that? Shouldn't it go through the onPause/OnResume as well?
When you get a phone call, it does go through onPause and onStop and when it is brought to the front again it goes through onStart and onResume. It may also be going through onDestroy which will cause it to go through onCreate when you bring it back. Suggest putting Log statements in each of the lifecycle methods to see which are getting called (or breakpoints in the debugger). Then you'll know what approach to take to resume your game.
In reality, you should implement the app such that it can go through onDestroy and recover when starting up again in the way you want.
When your app goes into the background, the Android OS decides if it should kill the app based upon current factors (e.g. available memory). If there are insuffuicient resources to maintain an app in the onPaused() state then they are destroyed (onStop() followed by onDestroy()).
Shouldn't it go through the onPause/OnResume as well?
Based upon the above and documentation, then yes it does go into onPause but then it goes into the other phases afterward.
Here is a handy image to help from the documentation that i know you read.

Activity life cycle in jelly bean is different

I have a strange behavior in my app when running in jelly bean 4.1.1 , when i start an Activity and press the back button to go back to the First Activity it re-create it by calling onCreate also , what i did also i handle the configuration change with the first activity so it won't recreated on configuration change but thats didnt make anything . !!!! why Activity life cycle in jelly bean have a strange behavior. You can see what i mean , just create a simple Android project and create two activity , navigate from the first one to activity to and press back button and see the logs onCreate on Activity 1 will be called !!!!
There is no guarentee that the OS won't kill your background Activities at any time if it determines that it needs the resources. Just a guess, but onCreate may get called in these cases because the system kills the first Activity before you get back to it.
Edit: http://developer.android.com/guide/components/activities.html#Lifecycle
If an activity is paused or stopped, the system can drop it from memory either by asking it to finish (calling its finish() method), or simply killing its process. When the activity is opened again (after being finished or killed), it must be created all over.
Here is another reference for you:
http://developer.android.com/training/basics/activity-lifecycle/recreating.html
http://developer.android.com/training/basics/activity-lifecycle/starting.html
In the first link:
The system may also destroy your activity if it's currently stopped and hasn't been used in a long time or the foreground activity requires more resources so the system must shut down background processes to recover memory.
...
However, if the system destroys the activity due to system constraints (rather than normal app behavior), then althought the actual Activity instance is gone, the system remembers that it existed such that if the user navigates back to it, the system creates a new instance of the activity using a set of saved data that describes the state of the activity when it was destroyed. The saved data that the system uses to restore the previous state is called the "instance state" and is a collection of key-value pairs stored in a Bundle object.
Open Phone setting screen
click on developer option(if not present then press about phone 5-6 times)
In developer option in App category uncheck Do not keep Activities flag

Categories

Resources