How do you recreate an activity within itself without saving its instance? - android

I want to use recreate() to relaunch my activity, but I don't want it to execute the onSaveInstanceState(). So, it's really like, launching a new activity.
On this page, an answer says that:
Since API level 11 (Honeycomb), you can call the recreate() method of the activity (thanks to this answer).
The recreate() method acts just like a configuration change, so your onSaveInstanceState() and onRestoreInstanceState() methods are also called, if applicable.
Is there any other way to relaunch an activity within itself without calling onSaveInstanceState()?
If you consider this bad practice, what do you think I should do?

have a look here.
onSavedIstanceState and onRestoreInstanceState are always called, but if you don't implement them they will recreate the app without doing anything :)
EDIT: you can add a new save to them, like an int.
when you reload but you don't wanna restore anything, you set this value for example at 1.
when you reload and you want to preserve it you set it for example at 0.
than in onRestoreIstanceState you check for this value, and if it is 1 you don't call any of reload calls, if it is 0 you call them :)

This may not be good way, but the way I handled is reusing the intent that starts the activity.
Define an intent intentOLD in the onCreate method and use
intentOLD = getIntent() to retrieve the Intent that starts this activity. Then when you want to restart the activity, call finish(); startActivity(intentOLD);

Related

Android: recreate() doesn't clear EditTexts

I'm actually using recreate() method to restart an Activity, but this method doesn't clear the EditTexts inside the Activity.
How can i solve this?
If you just want to clear your EditText without recreate the entire activity, you should use setText() method to clear it properly.
Like this:
yourEditText.setText("");
As per the documentation for recreate, the call to recreate Cause the Activity to be recreated with a new instance. This results in essentially the same flow as when the Activity is created due to a configuration change -- the current instance will go through its lifecycle to onDestroy() and a new instance then created after it.
So basically recreate() doesn't actually act the same way as totally recreating the activity.
For example: if you have any Fragments with setRetainInstance(true) they won't be recreated; merely paused and resumed.
One more catch with recreate API is it is supported from API Level 11 and Above. Hence, use of recreate is ok if your app is only targeting SDK level 11 and above.
Check if you are using the setRetainInstance(true) in your code.
You need to may be show more code to understand the specific problem!

OnCreate method is always called

I read the Android documentation and I don't understand one step:
When I press a button my app shows the Activity2 with the startActivity(intent) method, then I use the back button and my app shows the Activity1 again. If I want show the Activity2 I press the button again, and my app always call onCreate to the Activity2.
The Android documentation says the method onCreate is called only when is starting or when is destroyed.
Why is this happening?
Thanks!!
Regars.
The OnCreate() method is called each time the activity is displayed (created). So each time you call the startActivity(intent) method, the OnCreate method will be called.
Check the Activity Lifecycle for more information.
It's because you pressed the back button when you were in Activity2, which by default destroys the activity you're currently on. You can override onDestroy() and print a debug message to confirm (make sure to call super).
Instead of retaining the same Activity2 object, you should leverage onSaveInstanceState(Bundle) and onRestoreInstanceState(Bundle) to save and restore your Activity2's state, respectively.
Technically you could use the Bundle object passed into onCreate(Bundle) as they are the same object. The docs recommend onRestoreInstanceState(Bundle):
Most implementations will simply use onCreate(Bundle) to restore their state, but it is sometimes convenient to do it here after all of the initialization has been done or to allow subclasses to decide whether to use your default implementation.
It's completely normal beheviour. You are calling startActivity() so activity is starting. That's all. This method is called also when you are changing configuration - i.e rotating the device. Moreover - it's also possible that Activity1.onCreate() will be called after pressing back button, while it's going background and can be disposed by system if more ram is needed.

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.

Android launch intent from onCreate

In my Activity onCreate method I create and Intent (say to launch the camera) and call startActivityForResult. The problem is that onCreate is called twice and the Intent is launched twice. Both are received in onActivityResult.
What is going on here? How should I automatically launch an Intent when my Activity loads? I tried calling startActivityForResult in onStart, but it is still called twice.
Thanks.
onCreate is normally called when you return from another activity, like in your example. The activity lifecycle docs by Google are a bit misleading in this respect (they make you think onCreate only called once during the app lifecycle).
Your best bet is to save your state in onSaveInstanceState, e.g. add a cameraCalled flag, and then check that flag in onCreate to prevent a loop.
onCreate may and may not be called when you are returning.
It will depend on memory situation and whether or not OS killed your activity. You will need to account for both scenarios. It is probably not doable when you call from onCreate. See this for more information on order of what is called on the return State of Activity while in onActivityResult question

Categories

Resources