So my app allows users to set a specific orientation in the preferences.
Then I call in the activity the next method
setRequestedOrientation(#ActivityInfo.ScreenOrientation int requestedOrientation)
But I also want to know if it's going to trigger activity recreation so I would not init other
stuff
Is it possible to know if will recreate an activity?
Related
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);
Hi guys i have an app which is almost totally complete.It is a music player.It plays music from a service.
When i press back button that activity which started the service is obviously destroyed.(i want the activity to be destroyed so that the user can navigate other activities.The reason i am telling this is because singleton|singleinstance etc won't solve my problem) But i don't know how i can recreate the activity from the notification.
Also when the activity which started the service is visible(and not destroyed) then too if i click on the notification, my app stops unexpectedly.And hence i have two problems to solve here.
I am using a global variable which is a list and hence i don't think i need to save data before destruction.I think i know the concept how the activity state can be restored and recreated but i think i am not totally aware how it can be done.I am not sure in which method the activity state should be restored and how can it be restored ??Also i am starting the service in onCreate method.Should i change it to some other method?Can starting the service in onCreate be a problem when restoring the activity ?
Extra Note :Global Variables are available throughout the application and are independent of an individual activity,as they extend Application.Also Bundle will only help when the activity is destroyed by the system.When Pressing the back button we explicitly destroy the activity and hence data cannot be saved into the bundle as onSaveInstanceState is never called by the activity.
Activity state should be restored in onCreate. The onCreate method gets a Bundle as parameter which contains key-value pairs of data. If this parameter is null, it means that no previous state was saved. Just check if it's not null, and restore things if necessary:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(...);
...
if(savedInstanceState!=null) {
// Restore activity state based on saved data!
}
}
Of course you need to save data if you want to use it at restoration. System automatically calls the activity's onSaveInstance state method in which you can put data into the bundle.
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putInt("key", value); // Store data
}
Please note that this all applies to the case when system destroys your application automatically. (For example, when other apps in the foreground run out of memory.) This mechanism is to get your activity back to a state in which the user last saw it.
If the data is consistent and reflects with the Service, then you need to bind to the Service and get the data from the IBinder (which can wrap a Service object). I, personally, prefer this method because I simply don't like overriding the Application.
An alternate method is to save data via the SharedPreferences. Save it your Activity state in onPause() and restore in onCreate(). Assuming you're not saving hundreds of items, it is very low overhead. This should only be used for data that reflects the state of the Activity itself.
You can play and stop your player based on Activity life cycle like
OnPause -you should call player.stop()
onresume you should call play and
ondestroy you need to release your player instance.
call a thread inside your service to get data from server so that it will work smoothly.
you should release mediaplayer instances by calling release or reset .
You can use Pending intent in notification so when you will see notification then you can open your activity whatever mentioned in pending intent.
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 .
I know this is a duplicate question, and I know that when the device is rotated, the OnCreate method is called again, and I want to keep it like this; I don't want to go through the steps of overriding onConfigurationChanged or sub-classing my Application class because android is doing the reloading in the best way (especially on saving current values and status).
However, I have some commands inside the OnCreate method which I don't want to execute them if the Activity is reloaded due to Rotation, so is there any property/method that can tell if OnCreate is triggered due to first Application start or due to Orientation change?
For example:
if(< OnCreate triggered due to Orientation > == false)
// Execute my commands...
else
// Do nothing...
Alternatively, do we have any events in Android to be triggered before OnCreate or before OnConfigurationChanged?
Why not store the current orientation in SharedPreferences and compare the current orientation to the stored value in onCreate (and then save the new orientation to SharedPreferences)?
That should provide the functionality that you require, unless I've misunderstood something.
Try using onSaveInstanceState, if you want to save some state information before your activity gets destroyed and then onRestoreInstanceState to retrieve it.
You can also use getRequestedOrientation() in onCreate to get the new Orientation.
You can also use this in onCreate()
Display display = ((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
int orientation = display.getOrientation();
The Activity class has a special
method called
onRetainNonConfigurationInstance().
This method can be used to pass an
arbitrary object your future self and
Android is smart enough to call this
method only when needed.
Read more here.
Here is the scene what i am facing..when i press home key it saves the current state of the current activity..so when my app comes in foreground, onResume() of that particular activity gets called who's state was saved. So if an app with say 10 activities are there then, we will need to write reload of app data in each activity's onResume()..is there a way to specify a reload of app data in one activity only..?
Jitesh,
Yes, this is possible. You will probably want to perform the reloading of application data in your Activity's onResume() function. See Android Activity Lifecycle.