Preventing from onDestroy being called screen off button pressed - android

I have Activity that gets populated with info. When I press the screen off button and come back to the Activity, the info is not there anymore.
Btw, If I use the home button the info doesn't disappear. On logs, it shows it doesn't call onDestroy;
Therefore, onDestroy discards the info. I don't want onDestroy. HOw could I make that happen.
Thanks.

OnDestroy will always be called. You should save data and than recreate Activity on onCreate. Everything is nicely explained here. Read section "Saving Persistent State". Also read about lifecycle of Activity.

Try to save activity's info on onSaveInstanceState() and restore the state on onRestoreInstanceState().
This approach also helps you also in configuration changes state.
onSaveInstanceState() is called before destroying activity and onRestoreInstanceState() is called just before recreating the activity.
Follow this for more details.

Probably duplicate of Android activity onDestroy() called on screen lock.
This behaviour usually occurs at landscape orientation activities. Add
android:configChanges="orientation|keyboardHidden|screenSize"
to your AndroidManifest.xml activity tag.

Related

abnormal behavior of parent activity after finishing child activity

I have Activity A and I am calling Activity B from Activity A using setResultForActivity.
Now in Activity B when I press Done button I am firing finish() and it returns to
Activity A and it return down to onActivityResult. Now the issue is after when I fired finish() in Activity B , Activity A's onCreate doesn't get called and thats why
some of the custom listeners in my ListView isn't working , it seems that they are not bind.
so the whole activity respond pretty weirdly , can anyone has solution to this ?
Why a fourth answer? Because in my view, the others aren't fully correct.
Truth is, Activity A could have been destroyed in the meantime, or not. This depends on whether Android needs memory or not. So it is possible that Activity A´s onCreate() is called (along with the other lifecycle callbacks), or not. In the latter case, onActivityResult() is called before onResume().
While for configuration changes, the most efficient way to preserve the Activity's state is via nonConfigurationState, if you want to prepare for a restart of your Activity after it has been destroyed, you can use the InstanceState mechanism, because while Android destroys your Activity A, it will keep its intent and saved instance state to re-crearte it.
This stresses the absolute necessity to place initialization exactly in the callback where it belongs.
To test whether your Activity logic works regardless of whether Android destroyed it or not, you can use the DevTools setting "Development Settings" -> "Immediately destroy activities". The DevTools app is available on AVDs and can also be downloaded from Google Play.
Just place your onCreate() stuff in onResume() of Activity A except setContentView().
Just have a read on Android Activity Lifecycle : http://developer.android.com/training/basics/activity-lifecycle/stopping.html. onCreate() is only called when the activity is first created. You can do your list thing in the onResume() method.
Activity A's onCreate won't get called because the activity has not been destroyed. When an Activity regains focus from another activity, it's onStart and onResume get called, so I would put your bound listeners in those. They will also be called when onCreate is normally called.
After your child activity is finished() it return to execute onActivityResult which is in your case in Activity A. The onCreate method is not supposed and does not get called when killing of you sub-activity, a.k.a Activity B.
Please post some source code for us to work on and I will improve my answer! :)

Setting flag in onSaveInstanceState() to determine exit type in onDestroy()

For online games, it would be great to know if an Android Activity's onDestroy() is only called because Android is going to re-create it (e.g. device rotation) or if the user opted to exit the game.
My plan was to set a flag in the Activity's onSaveInstanceState() when Android is probably re-creating the Activity:
private boolean mDestroyedForReCreation;
...
protected void onSaveInstanceState() {
...
mDestroyedForReCreation = true;
}
If you did this, you can check mDestroyedForReCreation in onDestroy():
If the flag is set (true), don't dismiss the user from the online game.
If the flag is not set (false), dismiss the user from the online game as he did voluntarily exit the game.
Is that a correct approach? And if yes, is it recommended or is there any better solution? I hope so because I don't really like that solution ...
I suggest you to remove such kind of game logic from activity's life cycle. Create a Service. If no one binded - all activities are dead. Is someone binded - keep working.
If you do not want to create service, you can use onRetainNonConfigurationInstance method. Here is example.
You should use onRetainNonConfigurationInstance because it is called by the system, as part of destroying an activity due to a configuration change, when it is known that a new instance will immediately be created for the new configuration. onSaveInstanceState called when android going to kill activity and maybe restore it sometimes or maybe not ).
You can simply avoid restarts on rotation by handling this configuration changes by code. You can do this in your Manifest.xml like this:
<activity
android:name=".MainActivity"
android:configChanges="orientation|screenSize|keyboard|keyboardHidden"
android:label="#string/app_name" >
So your app won't restart on rotation and if the keyboard opened/closed.
I think this solution is much simpler.
In this case you almost don't need to handle onSaveInstanceState() for exiting, except you start another intent/activity where you need to save your game state. Note that a phone call will also interrupt your code. I know some games with funny bugs where the time is resetted but not the score.
I would just simplify the whole thing, and set a flag that is toggled when the user exits the game, something like:
void exitGame() {
mUserExited = true;
finish();
}
(Or you might need more logic if you need to destroy multiple activities)
Then check the flag in onDestroy().
Whatever logic you have about configuration changes (rotation, etc.) will have nothing to do with the exit game flag.
Also, remember that the 'back' button's default behavior is to finish() the current activity (if nothing else is above it) - that won't count as an "exit" in this case. The behavior here is up to you.
Activity has a method called isFinishing() that is probably what you are looking for.
See: https://stackoverflow.com/a/9621078/445348
If you need to know this, you should consider handling rotation and other configuration changed events yourself rather than letting the system do it. If you set in your manifest that the activity handles configChanges, it will call onConfigChange when it rotates rather than destroying and recreating the activity. A large amount of apps do this, the whol destroying and recreating on rotation thing Android does is absolutely retarded.
onRestoreInstanceState() will be called if when it is restored /recreated , if the activity if killed by android it saves its activity UI state and some values you can override onSaveInstanceState
but because onSaveInstanceState() is not guaranteed to be called, you should use it only to record the transient state of the activity (the state of the UI)—you should never use it to store persistent data. Instead, you should use onPause() to store persistent data (such as data that should be saved to a database) when the user leaves the activity. Also onRestart will be called after onStop() when the current activity is being re-displayed to the user. So probably you can save your state in onPause / if onRestart is called it is like it is being re displayed , while if onCreate is called without onRestart it is recreated . Other solution is to use singleInstance and override method onNewIntent which is called if activity is not destructed but like restarted on a new intent .

What happens when new activity is started?

I'm calling an Intent from an activity: I want to know what happens with the activity when I'm calling the Intent, I mean, is it destroyed? onPause? onStop?
This is what I use to call an Intent:
Intent intent = new Intent(context,class);
context.startActivity(intent);
I want to know that if I have a checkbox in an activity, so for example I check that checkbox and after I go to the next activity, but if I go back to the previous activity, the checkbox is not checked as it was when I call the Intent.
I don't know if I have explained my self, but I hope you can give me a hint to solve this.
By default, the activity is stopped, not destroyed. It might be destroyed if the system is low on resources.
So what's probably happening in your case is, the system gets low on resource so it destroys your activity. You should save your UI state in onSaveInstaceState, and restore it in onRestoreInstanceState. Read more here.
intent.putExtra("",""); Save chackbox state here
Put state of checkbox in shared preferences or static variable and once you go back to that activity , check for its state and populate it if that is the case
I mean, is it destroyed? onPause? onStop?
onStop is called.
From developer.android.com
onStop() - Called when the activity is no longer visible to the user.
Try saving the state of checkbox in static boolean with isChecked() and check that boolean in onRestart() - this is called, when you come back to your previous activity.
There are numerous prior questions on saving the state of a checkbox (whether due to intent or screen rotation). The same generate approach applies:
For instance:
How can I maintain the state of a CheckBox even after navigating to different activities in android?
And to determine the lifecycle calls being made, one can always override the methods with a call to super class and use breakpoints in the debugger. That has always been helpful to me to see the code in motion alongside the Android lifecycle diagrams.

Why onRestoreInstanceState() never gets called

I am trying to save data in my activity and than restore it.
I save data in on onSaveInstanceState() and then I try to restore the data in onRestoreInstanceState().
I setup breakpoint, the method onSaveInstanceState() get called. But onRestoreInstanceState() or onCreate() never did.
Here is my steps:
start my Activity.
press 'Home' button on the phone. onSaveInstanceState() get called.
Click the icon in the launcher and launch my Activity again.
At this time, only onRestart() get called. But not onRestoreInstanceState() or onCreate().
Does anyone know why?
Well, if onRestart() is called, the value of the instance variables would be maintained by the application stack itself and thus you do not need to restore them.
onCreate() method is only called when your Activity's onStop() is called and the process is killed.
Please refer the Activity life cycle Android Activity Life Cycle for a clear understanding.
You may want to check whether the onStop() method is called and if your process is killed. I do no think that your process gets killed by the scenario which you have described.
the onRestoreInstanceState() method is very tricky. I do not know when exactly it is called but I saw it was called once while changing from Potrait to Landscape.
From doc:
The system calls onRestoreInstanceState() only if there is a saved state to restore.
I have asked similiar question earlier on here
Here's some steps to test out onRestoreInstanceState():
Press home screen
Kill the app through adb
Launch your app again
Follow these steps (Using Android Studio):
Create New Logcat Filter, e.g. AppState
Launch the app on your emulator. You will see:
I/AppState﹕ onCreate
I/AppState﹕ onStart
I/AppState﹕ onResume
Press Ctl-F12 to rotate the emulator. You will see:
I/StateChange﹕ onPause
I/StateChange﹕ onSaveInstanceState
I/StateChange﹕ onStop
I/StateChange﹕ onDestroy
I/StateChange﹕ onCreate
I/StateChange﹕ onStart
I/StateChange﹕ onRestoreInstanceState
I/StateChange﹕ onResume
This causes the destruction and recreation of the activity by making a configuration change to the device, such as rotating from portrait to landscape.
See the link below for how to test onSaveInstanceState() and onRestoreInstanceState() on a real device or in the emulator.
This method uses the AlwaysFinish setting, which is simpler and faster than killing processes. This method also provides Activity-level control rather than process level control:
http://bricolsoftconsulting.com/how-to-test-onsaveinstancestate-and-onrestoreinstancestate-on-a-real-device/
This is my solution for real device so onRestoreInstanceState get it called.
in manifest on related activity remove this part android:configChanges="orientation"
in manifest on related activity remove this partandroid:screenOrientation="portrait"
in your activity remove this line if it's there setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
on your device enable rotating from setting - display - auto rotate.
then run your app, rotate your device.
that's it.

Interactivity Coordination: onStop and onResume

I have two activities. One loads all rows from a database, and the other saves to the database. When I have the second save in onStop and the first repull the data in onResume, they do it out of order (the first resumes and then the second saves). I managed to fix this by putting the saving data in onPause, but why was this happening? Was this the cleanest way to do it?
Doing the save in the first actvity's onPause should be fine.
You've discovered that the foreground lifetime of an activity happens between a call to onResume() until a corresponding call to onPause(). During this time, the activity is in front of all other activities on screen and is interacting with the user.
When you start the second activity, onPause is called on the first and then interactive control switches to the second, with onStop on the first to be called somewhat in background.
This improves responsiveness and gets the new activity in front of the user ASAP. Consequently, you should try to keep your onPause implementation as fast and efficient as possible.
See the following Android docs for more details on the lifecycle http://developer.android.com/guide/topics/fundamentals.html, but what you have found should work fine for you.
Some official quote as an add-on:
The Activity documentation states that
onPause() is where you deal with the user leaving your activity.
Most importantly, any changes made by the user should at this point be
committed

Categories

Resources