I am new to java and android studio and after reading documentation I am still a little confused with the activity lifecycle and how to use it effectively.
I am building an application which has several activities. There is key data loaded in when the app is first opened in the main activity. However when I move to another activity and then back to the main, the onCreate is invoked again which I do not want. I am aware there is a way to save the instance of your onCreate but I am still unsure of how to do this. Here is what I have done:
#Override
protected void onSaveInstanceState(#NonNull Bundle outState) {
super.onSaveInstanceState(outState);
if (outState != null) {
// Restore value of members from saved state
outState.putString("step_count", String.valueOf(stepCount));
outState.putString("cal_count", String.valueOf(calCount));
outState.putString("dis_count", String.valueOf(disCount));
android.util.Log.d(TAG, "onSaveInstanceState");
} else {
// Probably initialize members with default values for a new instance
}
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
savedInstanceState.getString("step_count", String.valueOf(stepCount));
savedInstanceState.getString("cal_count", String.valueOf(calCount));
savedInstanceState.getString("dis_count", String.valueOf(disCount));
stepCount.setText(String.valueOf(stepCount));
calCount.setText(String.valueOf(calCount));
disCount.setText(String.valueOf(disCount));
android.util.Log.d(TAG, "onRestoreInstanceState");
}
Would appreciate any sort of support and guidance. Thank you.
Again - not a simple question.
First of all: Yes, you can save data "from last session" by overriding: onSaveInstanceState() and restore it overriding onRestoreInstanceState(savedInstanceState: Bundle?). Look here: https://developer.android.com/guide/components/activities/activity-lifecycle#saras
Second of all: According to your description it seems that you need SharedPreferences more than this. If you need a key to anything and it should be used from opening of the app until it is killed or user is logged out, SharedPreferences are the most common solution.
onSaveinstanceState() was created to make possibility to remember what was on the screen "in the last session" without "calculating" it again. For example EditText.text or ImageView.url or similar.
Related
As the title says.
Specifically, I am writing an app that prints data to files over the course of runtime. I want to know when I can tell my PrintWriters to save the files. I understand that I can probably do autosave every X minutes, but I am wondering if Android Studio will let me save on close instead. I tried using onDestroy but the code block never executed. (To be precise, I started the app, did a few things, closed the app, clicked Recents, and swiped the app away. The debugger showed that the app never got to that code.)
My current solution attempts to catch the surrounding circumstances by checking for key presses but this only works for the back and volume buttons and not the home, recent, or power buttons.
#Override public boolean onKeyDown(int key, KeyEvent event) {
close();
return false;
}
There's a built in hook to the Activity lifecycle to save your state- onSaveInstanceState. There's even a bundle passed into you to save your state into for it to be restored (the matching function is onResumeInstanceState). And as a free bonus, if you call super.onSaveInstanceState and super.onRestoreInstanceState, it will automatically save the UI state of your app for all views with an id.
Please check the activity lifecycle:
https://developer.android.com/guide/components/activities/activity-lifecycle
Or if you're using a fragment:
https://developer.android.com/guide/fragments/lifecycle
Consider using one of these two:
#Override public void onStart() {
super.onStart();
close();
}
#Override public void onPause() {
super.onPause();
close();
}
I'm trying to get an app to show all the users online... I'm using the following way to achieve it
#Override
public void onStart(){
super.onStart();
mDatabaseReference.child("Online").setValue(true);
}
#Override
public void onStop(){
super.onStop();
mDatabaseReference.child("Online").setValue(false);
}
I'm not using ondisconnect because it shows offline only if the app is completely closed(not running in the background). SO i used this method on each activity... But the problem is that whenever i open an activity it shows online and the next second turns offline... I'm guessing that its because the prev activity closes after opening the new activity so the presents activity's on start is executed before the next activity's on stop. So since the activity's onstop is executed last it shows offline. How do i solve this problem
Your guess is completely correct.
Starting a new Activity will cause the onPause() and onStop() methods to be called for the first Activity.
Based on your description, I'm assuming that you want the Online status to remain true for as long as the app remains in the foreground and you are putting it in every Activity because your app doesn't only open from a single main Activity.
Your current code will work without a problem if you switched to using a Single-Activity Architecture, which is simply to use a single Activity and have it display different Fragments instead of new Activities. This solution will work with your existing code because onStop() and onStart() will only be called when your app enters the background.
If you look at the Navigation section in the official Android Developers Blog, you'll see that Google wants to encourage developers to switch to using the Single-Activity Architecture.
However, if you still wish to use multiple Activities, then you might want to consider an alternative way to keep track of Online status to take into account of multiple Activities.
For example, rather than using a simple boolean value, you can use an int value.
#Override
public void onStart(){
super.onStart();
mDatabaseReference.child("Online").addValue();
}
#Override
public void onStop(){
super.onStop();
mDatabaseReference.child("Online").removeValue();
}
With the addValue() and removeValue() being:
private void addValue(){
activityCount++;
onlineStatus = true;
}
private void removeValue(){
activityCount--;
if(activityCount <= 0)
onlineStatus = false;
}
Please keep in mind that this is only an example and doesn't take into account of how your app is designed. Bottom line is, you'll have to think of a solution that takes into account of multiple Activities that are displayed.
I do heavily suggest the Single-Activity approach.
When turn the switch on it stays on.. however when i leave the activity and come back to it.. it goes back to off. I want it to stay ON OR OFF depending on whats last pressed. I have tried the code below but does not resolve my issue
SwitchButton.setChecked(true);
SwitchButton.setChecked(false);
What you need to do is override these methods in your activity:
#Override
protected void onSaveInstanceState (Bundle outState){
super.onSaveInstanceState(outState);
outState.putBoolean("CHECKED", SwitchButton.isChecked());
}
then in onCreate:
#Override
protected void onCreate (Bundle savedInstanceState){
super.onCreate(savedInstaceState);
if(savedInstanceState != null){
boolean isChecked = savedInstanceState.getBoolean("CHECKED");
SwitchButton.setChecked(isChecked);
}
}
If you are minimizing the activity and then returning back to it, and you want all controls to retain their states, then look into implementing saved instance state. This will persist the control values while you minimize / maximize the activity or rotate it. No data is permanently saved to the device. Sample code here:
http://developer.android.com/training/basics/activity-lifecycle/recreating.html#SaveState
If you are closing the app completely and want the app to remember the settings, then consider SharedPreferences, which can be used to save data locally on the device. The data persists until your app explicitly deletes it or you uninstall the app. Sample code here:
http://developer.android.com/training/basics/data-storage/shared-preferences.html
I am new to android. I am doing a sample project on calculation of numbers. And i am using both portrait and landscape layouts. Whenever I change the orientation, my activity is newly created and all the previously entered values get lost. So, I tried to stop activity recreation by android:configChanges="keyboardHidden|screenSize|orientation" and by setting orientation only to android:screenOrientation="portrait". But this makes my portrait layout to fit in landscape mode. But I don't want this. I need to load my separate portrait and landscape layouts on orientation change with same set of values which was previously created(i.e load different layouts without activity recreation).
And also I tried of using overridden methods like onConfigurationchanged, onSaveInstanceState, onRestoreInstanceState. But still values are lost in using onConfigurationchanged method , and activity is recreated in using onSaveInstanceState and onRestoreInstanceState methods (Still the previous values are retrieved here).
Any solution for this?
Thanks in advance.
To resolve this you need to save and retrieve data in/from saved instance state
#Override
protected void onSaveInstanceState(Bundle outState) {
// TODO Auto-generated method stub
super.onSaveInstanceState(outState);
// Example to save the value of editText01 in SavedInstanceState
String stateToSave = editText01.getText().toString();
outState.putString("saved_state", stateToSave);
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onRestoreInstanceState(savedInstanceState);
//To Retrieve data from "saved_state"
String stateSaved = savedInstanceState.getString("saved_state");
edittextEditState.setText(stateSaved);
}
}
}
you should look at the onPause{} and onResume{} methods of the activity. because whenever your orientation is changed the activity is paused and then recreated again so you data is lost. and to understand better you should take a look at the activity life cycle
http://developer.android.com/reference/android/app/Activity.html... :)
delete android:screenOrientation="portrait" and give this code, android:configChanges="keyboardHidden|screenSize"
i have an app that has three pages, one of them is the main page. the user can enter in a few fields that i would like to save if the user goes to one of the two sub pages. i have been looking into the onPause() and into onSaveInstanceState(). i guess i just want a clear explanation on the two, and if onPause() is better and example of the code. this is what i ahve for onSaveInstanceState().
protected void onSaveInstanceState(Bundle outState) {
// Save away the original text, so we still have it if the activity
// needs to be killed while paused.
outState.putDouble("quizPts",qpts);
outState.putDouble("quizV",qvalue);
outState.putDouble("tPts",tpts);
outState.putDouble("tValue", tvalue);
outState.putDouble("hPts", hpts);
so that is how i am setting up bundle, by giving it an ID and a value.
public void onRestoreInstanceState(Bundle outState) {
super.onRestoreInstanceState(outState);
// Restore UI state from the savedInstanceState.
// This bundle has also been passed to onCreate.
qpts = outState.getDouble("quizPts");
qvalue = outState.getDouble("quizV");
tpts = outState.getDouble("tPts");
tvalue = outState.getDouble("tValue");
hpts = outState.getDouble("hPts");
this is how i plan to retore it, the problem is i dont understand how to pass the Bundle around to restore it. i am setting the variables that i need to back to the variables that get set to the UI.
any advice would be great
thanks from a beginner androider
The best option will be a shared preference. The onpause is designed for attending your concerns when app is paused due to a phone call or something. But if you use shared preference it gives you the method for saving your data and recover it wit default values if the saved value is not available. This data will persist across user sessions (even if your application is killed). But it is not a good option if you are planning to save something other than primitive data types like bool,int etc.
see http://developer.android.com/guide/topics/data/data-storage.html#pref
You don't need to pass the bundle around yourself: the Activity framework takes care of that. Use onSaveInstanceState(): if your Activity class is destroyed for any reason by the system it will be called so you should be fine putting your logic in there. onPause will always be called if you leave your Activity, regardless of if the Activity is destroyed.
I would also add a check in your onRestoreInstanceState:
public void onRestoreInstanceState(Bundle outState) {
super.onRestoreInstanceState(outState);
// Restore UI state from the savedInstanceState.
// This bundle has also been passed to onCreate.
if(outState.containsKey("quizPts")) qpts = outState.getDouble("quizPts");
if(outState.containsKey("quizV")) qvalue = outState.getDouble("quizV");
if(outState.containsKey("tPts")) tpts = outState.getDouble("tPts");
if(outState.containsKey("tValue")) tvalue = outState.getDouble("tValue");
if(outState.containsKey("hPts")) hpts = outState.getDouble("hPts");