How to fully refresh android app after configuration change - android

I want that my activities are recreated from scratch when device cofigs like font size changes or app is launched after killed by OS. What's the best way to achieve this? By default lifecycle methods like onCreate etc are called but activity is not fully initialized.

Simply call the recreate method of the Activity:
recreate();

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!

Does onConfigurationChanged method change activity lifecycle

I am an Android Beginner. According to the lifecycle of an android application, when screen orientation is changed following methods are called:
onPause()
onStop()
onDestroy()
OnCreate()
onStart()
onResume()
But I have now added onConfigChanged in my XML file. When activity starts, onCreate, onStart and onResume are called. But when my screen orientation changes, only onConfigurationChanged method is called, the above mentioned methods are not called as shown below:
Any reason for this?
Thanks in advance.
Normally when an orientation , language , ... change happen the activity get destroyed and restarted and start the lifecycle from the begining unless you override the onConfigurationChanged function.
More details from Android documentation:
Configuration Changes
If the configuration of the device (as defined by the
Resources.Configuration class) changes, then anything displaying a
user interface will need to update to match that configuration.
Because Activity is the primary mechanism for interacting with the
user, it includes special support for handling configuration changes.
Unless you specify otherwise, a configuration change (such as a change
in screen orientation, language, input devices, etc) will cause your
current activity to be destroyed, going through the normal activity
lifecycle process of onPause(), onStop(), and onDestroy() as
appropriate. If the activity had been in the foreground or visible to
the user, once onDestroy() is called in that instance then a new
instance of the activity will be created, with whatever
savedInstanceState the previous instance had generated from
onSaveInstanceState(Bundle).
This is done because any application resource, including layout files,
can change based on any configuration value. Thus the only safe way to
handle a configuration change is to re-retrieve all resources,
including layouts, drawables, and strings. Because activities must
already know how to save their state and re-create themselves from
that state, this is a convenient way to have an activity restart
itself with a new configuration.
In some special cases, you may want to bypass restarting of your
activity based on one or more types of configuration changes. This is
done with the android:configChanges attribute in its manifest. For any
types of configuration changes you say that you handle there, you will
receive a call to your current activity's
onConfigurationChanged(Configuration) method instead of being
restarted. If a configuration change involves any that you do not
handle, however, the activity will still be restarted and
onConfigurationChanged(Configuration) will not be called.
It's a very good thing that only onConfigurationChanged() is called with orientation changes. It's actually preferred because it means that your initializations in onCreate() DON'T have to happen again -- you can reuse them with the new views that you rebind in onConfigurationChanged(). This results in a faster application that uses less memory and is less clunky.
Case in point:
You have a ListView. That ListView uses an ArrayAdapter. In onCreate(), you find the listView using findViewById(R.id.xxx) and you CREATE a NEW ArrayAdapter and set it for that listView. If every time onCreate() is called when the orientation changes, you would be creatting a new ArrayAdapter each and every time the orientation changes. Imagine switching the orientation 3 times -- what a waste!
Like this, you can create the ArrayAdapter in onCreate(), once, ever (when your application is created). And when the orientation changes, in onConfigurationChanged(), simply reset the ArrayAdapter for the new ListView you pick up again using findViewById(R.id.xxxx). Done. Only 1 ArrayAdapter has ever been created and it's data remains in tact for the new orientation.
Beautiful! :)

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 .

Application context gets killed but activity not

I'm working on an application which has a few Activities. One Activity starts the next one. To share some Values I'm using a custom implementation of Application (I'm talking about android.app.Application) called MyApplication.
As we all know, the Android system kills an app, if it needs more space. But this leads to a problem:
I open my app and use it just like any other app
I close it (Home Button) and use other apps
The system will kill my application because it's wasting memory
When I reopen my App, it wants to open the last activity I used and I get a force close, because the values in MyApplication are null
The strange thing is, that the system destroys my Application, but it seems like it keeps the Activity. I don't really understand why this is so because the Application doesn't seem to have a life cycle.
What I want to have:
When MyApplication (whole Application, not only the activity) gets killed, I want the last activities to be killed too. So when I reopen the App, it starts the main acitvity provided by the manifest.xml.
or
The values in MyApplication are persisted and don't get lost if the Application gets destroyed. (I'm talking about a few objects so i think the shared preferences won't work).
I don't want to use a service to bind my activities to, but is there a similar way to tell the system that my last used activity depends on the application-context?
I hope you understand what my problem is and someone can help me out with this.
The right way to do things would be to save your application state.
Override the onSaveInstanceState(Bundle savedInstanceState) method to save your state and onRestoreInstanceState to retrieve it.
If you need to save large sets of data consider using a SQL database
You should make sure the app closes and restarts the way you want it to in the onPause() , onResume() and onStop() methods. Check out savedInstanceState which can save the state of the app (and restore it, when it's sent as a parameter to onCreate)
In your custom implementation of Application, add a Flag say :
public boolean appContextExist = false;
On your first Activity set the flag to true,
Override onCreate and onResume method on your Activity which need the contexts, add following :
MyApplication myApp = ((MyApplication) getApplicationContext());
if (!myApp.appContextExist) {
// Code to return to start activity here
}

Android web app gets restart

I am facing problem in building android webview . The problem is that when the app is running and phone change direction , i mean from horizontal to vertical or vice versa the app get restarted. Thanks
The default behavior is to restart the activity when the screen orientation changes. You can write custom code to handle orientation change events yourself though:
Add android:configChanges="orientation" to your AndroidManifest.xml
Override onConfigurationChanged from your activity
The default android behaviour is to destroy and recreate the activity on orientation change. You can either override onSaveInstanceState() to save your application data before destroy, or you can call onRetainNonConfigurationInstance() to keep hold of a stateful object. See the android docs.
Umar,
You will want to add the android:configChanges="orientation" parameter to your Activity in your AndroidManifest.xml to prevent your activity from restarting on orientation change.
See: http://developer.android.com/guide/topics/manifest/activity-element.html#config
Another possibility (usually a decent fit for lighter Activities that don't have state outside a WebView, for instance) is to absorb the rotation event and let the view redraw itself. See http://www.androidguys.com/2008/11/11/rotational-forces-part-three/ - the idea is:
Put an android:configChanges entry in
your file, listing the configuration
changes you want to handle yourself
versus allowing Android to handle for
you.
Implement onConfigurationChanged()
in your Activity, which will be called
when one of the configuration changes
you listed in android:configChanges
occurs
See also: Activity restart on rotation Android
umar... Saving instance state is quite different on the Android. On a soft kill (phone rotation) you may save your non view state in onSaveInstanceState using bundles. On a hard kill (back button while activity has focus) you may elect to save your non view and view state in onStop perhaps using preferences. You can restore your state in onCreate.
You can leverage the fact that IF onSaveInstanceState is called it will be called BEFORE onStop. So this lets you set a flag isSavedInstanceState to true in onSaveInstanceState to avoid saving prefs in onStop except on a hard kill. The trick is to reset the flag isSavedInstanceState to false in onResume NOT in onCreate.
JAL
I have sample code here.

Categories

Resources