A variable is reset after some time - java

There's an int variable accessed via singleton pattern.
But the problem is that the variable is set once and it's reset to 0 after some time.
It seems to be reset by garbage collection. Saving the value in Activity.onSaveInstanceState and restoring it in onCreate() is non-working.
Is the solution to save the variable in disk?
I just want to prevent it from resetting.

The variable will only stay active as long as the application is active. Android is notorious for killing background processes automatically. Unfortunately, if you're trying to access a variable that you'd like to persist over multiple runs of the application, you will need to write it to disk somehow.
There are a couple of options open to you, however. I will list the ones Google recommends.
Shared Preferences, "Store private primitive data in key-value pairs."
Internal Storage, "Store private data on the device memory."
External Storage, "Store public data on the shared external storage."
SQLite Database, "Store structured data in a private database."
Network Connection, "Store data on the web with your own network server."
Of all of these solutions, Shared Preferences, is probably the easiest to implement. It is as simple as:
public class Calc extends Activity {
public static final String PREFS_NAME = "MyPrefsFile";
#Override
protected void onCreate(Bundle state){
super.onCreate(state);
. . .
// Restore preferences
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
boolean silent = settings.getBoolean("silentMode", false);
setSilent(silent);
}
#Override
protected void onStop(){
super.onStop();
// We need an Editor object to make preference changes.
// All objects are from android.context.Context
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean("silentMode", mSilentMode);
// Commit the edits!
editor.commit();
}
}
Code is from the Android Data Storage page.

I just want to prevent it from resetting.
You can use the SharedPreferences to save and then retrieve the variable later. A tutorial on how to do so can be found here.
On a side note though, are you sure your variable is resetting because of garbage collection?

Related

Entering app exactly as it was left

I know there must be douzens of answers to this question out there, but either i cant't find them or I don't understand them.
The Question:
How do I get my app to exactly start as it was left?
F.e. dynamicly added checkBoxes shouldn't dissapear!
There is no "out of the box" way of doing it. You could save the current state of your Activity in some way (More on persistence)
Then you need to be able to rebuild the desired state of the persisted state in your Activity lifecycle
You could save and load with the shared preferences for example:
public void saveState(YourState state) {
SharedPreferences sharedPreferences = app.getSharedPreferences(R.string.preference_file_key, Context.MODE_PRIVATE)
sharedPreferences.edit()
.putString("CustomAtt", state.getCustomAtt())
}
public YourState loadState() {
SharedPreferences sharedPreferences = app.getSharedPreferences(R.string.preference_file_key, Context.MODE_PRIVATE)
String customAtt = sharedPreferences.getString("CustomAtt", "DefaultValue")
return new YoutState(customAtt)
}
And use it like this
#Override
protected void onCreate(Bundle savedInstanceState) {
YourState state = loadState();
// Rebuild your activity based on state
someView.setText(state.getCustomAtt())
}
You can store such values in SharedPreferences.
https://developer.android.com/training/basics/data-storage/shared-preferences.html
It is using key-value approach for saving. So you can save some values and read it from SharedPreferences whenever you want to.
This is the best approach for small data, that can be used on the app launch. So you can quit your app and the data is still present - so can be read on the next app launch.
Or save the condition of your program to a text file, so that the program can "translate" it back into conditions before it stops, or what I do not recommend, it saves every object created with ObjectOutputStream.

Update Shared Preferences after restarting application

I use Shared Preferences to fetch and store a variable, I then fetch that variable across a different class. After I restart the app, the initial variable stored is to be updated by the new one. What I can see is that on quitting the application, I should set my shared preference to be cleared and then again fetch the fetch value.
However, the problem is that even on restart, the shared preference still store the older value and do not update themselves.
Here is the code where I initially save the value
protected void onLoginSuccess(String cookieString, String userName) {
// set cookie and initialize data center.
mCookieString = cookieString;
SharedPreferences settings =getSharedPreferences("cookie",MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();
editor.putString("cookie", cookieString);
editor.commit();
//editor.apply();
mDataCenter = new LsApiDataCenter(this, userName);
mCachedUserData.clear();
System.out.println("shhhhhhhhhhhh iis original : "+cookieString);
mSendersObservers.clear();
mMessageObservers.clear();
mNotificationObservers.clear();
Later, Upon exit I want the shared preference to be cleared and this is how I do it
protected void onLogoutSuccess() {
// clear cookie and data center.
SharedPreferences settings =getSharedPreferences("cookie",MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();
editor.clear().commit();
mCookieString = null;
mDataCenter = null;
mCachedUserData.clear();
mSendersObservers.clear();
mMessageObservers.clear();
mNotificationObservers.clear();
Finally, this is how I fetch them in a completely different class
SharedPreferences settings = mMainActivity.getSharedPreferences("cookie", Context.MODE_PRIVATE);
count = settings.getString("cookie","");
The problem is that the value which I get upon fetching is the old value and not the latest value since i am fetching a value provided by a server via api used when the user logs in. However, I get the old value and the latest value is not fetched.
Thanks
If you want to clear the value of cookie variable you can do like this
SharedPreferences settings =getSharedPreferences("cookie",MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();
editor.putString("cookie", null);
editor.commit();

Android save details screen

I am working on a small project that requires a details screen where the user inputs his details and they are permanently stored. The user must have the option to change the details as well if he needs to do so. I looked into the saved preferences library however it does not seem to offer such functionality.
To give a visual idea of what is required, something like this screen should be fine:
http://www.google.com.mt/imgres?start=97&num=10&hl=en&tbo=d&biw=1366&bih=643&tbm=isch&tbnid=aQSZz782gIfOeM:&imgrefurl=http://andrejusb.blogspot.com/2011/10/iphone-web-application-development-with.html&docid=YpPF3-T8zLGOAM&imgurl=http://2.bp.blogspot.com/-YRISJXXajD0/Tq2KTpcqWiI/AAAAAAAAFiE/-aJen8IuVRM/s1600/7.png&w=365&h=712&ei=rbX6ULTDCOfV4gTroIDoCg&zoom=1&iact=hc&vpx=834&vpy=218&dur=2075&hovh=314&hovw=161&tx=80&ty=216&sig=108811856681773622351&page=4&tbnh=155&tbnw=79&ndsp=35&ved=1t:429,r:4,s:100,i:16
Any help is much appreciated. Thanks in advance
You could easily use Shared Preferences to store user's details. Everytime the Preference screen is opened the stored data can then be extracted from the Shared Preferences and presented to the user for edit. ONce the edit is done the new data can be updated back in the the Shared Preferences.
Also look at this thread to see how this can be done.
Using SharedPreferences would be perfect for this kind of small amount of data which you want to store persistently.
// 'this' is simply your Application Context, so you can access this nearly anywhere
SharedPreferences prefs = this.getSharedPreferences(
"com.example.app", Context.MODE_PRIVATE);
To obtain from the preferences:
// You can equally use KEY_LAST_NAME to get the last name, etc. They are just key/value pairs
// Note that the 2nd arg is simply the default value if there is no key/value mapping
String firstName = prefs.getString(KEY_FIRST_NAME_CONSTANT, "");
Or to save:
Editor editor = prefs.edit();
// firstName being the text they entered in the EditText
editor.putString(KEY_FIRST_NAME_CONSTANT, firstName);
editor.commit();
You can achieve such functionality using SharedPreferences Class in android.
public void onCreate(Bundle object){
super.onCreate(object);
// Initialize UI and link xml data to java view objects
......
SharedPreferences myPref = getPreferences(MODE_PRIVATE);
nameView.setText(myPref.getString("USER_NAME", null));
passView.setText(myPref.getString("PASSWORD", null));
}
public void onStop(){
super.onStop();
if (isFinishing()) {
getPreferences(MODE_PRIVATE).edit()
.putString("USER_NAME", nameView.getText().toString())
.putString("PASSWORD", passView.getText().toString())
.commit()
}
}

Detect First Run

I am trying to detect if my app has been run before, by using this code:
(This is in my default Android activity)
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
Log.w("activity", "first time");
setContentView(R.layout.activity_clean_weather);
} else {
Log.w("activity", "second time");
setContentView(R.layout.activity_clean_weather);
}
}
When I first run the app it says first time, when I run it a second time, first time, and a third, first time....
I am using an actual Android device and I am not using the run button each time. I run the app once with the Eclipse run button, then I close the app and press on its icon on my phone.
Is there something wrong with my code?
savedInstanceState is more for switching between states, like pausing/resuming, that kind of thing. It must always be created by you, also.
What you want in this case is SharedPreferences.
Something like this:
public static final String PREFS_NAME = "MyPrefsFile"; // Name of prefs file; don't change this after it's saved something
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0); // Get preferences file (0 = no option flags set)
boolean firstRun = settings.getBoolean("firstRun", true); // Is it first run? If not specified, use "true"
if (firstRun) {
Log.w("activity", "first time");
setContentView(R.layout.activity_clean_weather);
SharedPreferences.Editor editor = settings.edit(); // Open the editor for our settings
editor.putBoolean("firstRun", false); // It is no longer the first run
editor.commit(); // Save all changed settings
} else {
Log.w("activity", "second time");
setContentView(R.layout.activity_clean_weather);
}
}
I basically took this code directly from the documentation for Storage Options and applied it to your situation. It's a good concept to learn early.
You may use a self-defined shared preference to archive your goal.
The fact is that savedInstanceState holds persistent data across activities. As such if you restart the app, savedInstanceState will be null across runs. You should either use a Preference or some data base entry to keep track of your first run. I myself use a SharedPreference for this purpose.
savedInstanceState will be null if the app is not already loaded in memory. If you want to detect whether the app has run for the very first time, you have to apply different technique, such as using sharedPrefs / DB to store a property for the first run.
i.e. Check sharedPrefs for property "firstRun"
if exists, then it is not a first run
else it is the first run
set the firstRun property to true

Getting java.lang.nullPointerException using SharedPreferences

I am trying to save the date of file parsing, so that when next time user, opens the application, the date can be checked against the last parsing date.
I am using shared preference to save the data and retrieve it, but getting error. Here is the code :
SharedPreferences settings = getPreferences(0);
String today = new Date(System.currentTimeMillis()).toString();
SharedPreferences.Editor edit = settings.edit();
System.out.println("******** Today : " + today);
edit.putString("lastdate", today);
String fetch = settings.getString("lastdate", "0");
System.out.println("******** Fetch : " + fetch);
txtTest.setText(fetch);
But I am getting null pointer error, am I missing something?
Many applications may provide a way to capture user preferences on the settings of a specific application or an activity. For supporting this, Android provides a simple set of APIs.
Preferences are typically name value pairs. They can be stored as “Shared Preferences” across various activities in an application (note currently it cannot be shared across processes). Or it can be something that needs to be stored specific to an activity.
Shared Preferences: The shared preferences can be used by all the components (activities, services etc) off the applications.
Activity handled preferences: These preferences can only be used with in the activity and can not be used by other components of the application.
Shared Preferences:
The shared preferences are managed with the help of getSharedPreferences method of the Context class. The preferences are stored in a default file(1) or you can specify a file name(2) to be used to refer to the preferences.
(1) Here is how you get the instance when you specify the file name
public static final String PREF_FILE_NAME = "PrefFile";
SharedPreferences preferences = getSharedPreferences(PREF_FILE_NAME, MODE_PRIVATE);
MODE_PRIVATE is the operating mode for the preferences. It is the default mode and means the created file will be accessed by only the calling application. Other two mode supported are MODE_WORLD_READABLE and MODE_WORLD_WRITEABLE. In MODE_WORLD_READABLE other application can read the created file but can not modify it. In case of MODE_WORLD_WRITEABLE other applications also have write permissions for the created file.
(2) The recommended way is to use by the default mode, without specifying the file name
SharedPreferences preferences = PreferencesManager.getDefaultSharedPreferences(context);
Finally, once you have the preferences instance, here is how you can retrieve the stored values from the preferences:
int storedPreference = preferences.getInt("storedInt", 0);
To store values in the preference file SharedPreference.Editor object has to be used. Editor is the nested interface of the SharedPreference class.
SharedPreferences.Editor editor = preferences.edit();
editor.putInt("storedInt", storedPreference); // value to store
editor.commit();
Editor also support methods like remove() and clear() to delete the preference value from the file.
Activity Preferences:
The shared preferences can be used by other application components. But if you do not need to share the preferences with other components and want to have activities private preferences. You can do that with the help of getPreferences() method of the activity. The getPreference method uses the getSharedPreferences() method with the name of the activity class for the preference file name.
Following is the code to get preferences
SharedPreferences preferences = getPreferences(MODE_PRIVATE);
int storedPreference = preferences.getInt("storedInt", 0);
The code to store values is also same as in case of shared preferences.
SharedPreferences preferences = getPreference(MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putInt("storedInt", storedPreference); // value to store
editor.commit();
You can also use other methods like storing the activity state in database. Note Android also contains a package called android.preference. The package defines classes to implement application preferences UI.
To see some more examples check Android's Data Storage post on developers site.
You need to change how you get the object
SharedPreferences settings = PreferenceManager
.getDefaultSharedPreferences(context);

Categories