I am interested in saving my data in shared preferences and loading data from them. I would like to know a proper way to do that :
I think case is clear for the Activity class, android offers onCreate and onDestroy in which we should save and load from prefs. I hope I'm not wrong :)
But if I have some class derived from Object like this
public class LoggerSingleton {
// Constants
private static final String LOG_FILE = "log";
private static final Integer MAX_LINES = 200;
// Variables
private static List<String> logsList;
private static Context appContext;
// class initialization is called first time you call getInstance
private static LoggerSingleton instance = new LoggerSingleton();
public static LoggerSingleton getInstance() {
return instance;
}
// Constructor
private LoggerSingleton() {
logsList = new ArrayList<String>();
appContext = MyApplication.getContext();
SharedPreferences settings = appContext.getSharedPreferences(LOG_FILE, Context.MODE_PRIVATE);
try {
JSONArray jsonArray = new JSONArray(settings.getString(LOG_FILE, "[]"));
for (int i = 0; i < jsonArray.length(); i++)
logsList.add(jsonArray.getString(i));
} catch (Exception e) {
e.printStackTrace();
}
}
public static String getLogs() {
return logsList.toString();
}
public static void appendLog(String newLog) {
String currentDateandTime = Utils.getMyDateTime();
newLog = currentDateandTime + "_" + newLog;
Log.d(appContext.getString(appContext.getApplicationInfo().labelRes), newLog);
logsList.add(newLog);
while (logsList.size() > MAX_LINES)
logsList.remove(0);
JSONArray jsonArray = new JSONArray();
for (int i = 0; i < logsList.size(); i++)
jsonArray.put(logsList.get(i));
SharedPreferences settings = appContext.getSharedPreferences(LOG_FILE, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();
editor.putString(LOG_FILE, jsonArray.toString());
editor.commit();
}
}
I call getInstance() inside MyApplication constructor.
My question is, when is my object created and when is destroyed ? How to catch the destroy event? How to save my string list into shared prefs properly?
I want to cover all the cases : when OS destroys my objects as not used for a long time, when users does "Force Stop" and restarts the app, when phone goes into shutdown and back.
I think I know what happens to activities, but what happens with class like this and it's data ? What happens with class derived from Application, when it is destroyed, are data from it lost? Same for class derived from BroadcastReceiver. Is there some general way to save data from all these classes into prefs?
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
LoggerSingleton.initLoggerSingleton(getApplicationContext());
}
}
init your singleton class in application(init on application was started) after you init your object in YourApplication (extends Application) you can access it from any activity in your application if application was killed by os on nest start it will be re-init your singleton
Small changes in your class
public class LoggerSingleton {
// Constants
private static final String LOG_FILE = "log";
private static final Integer MAX_LINES = 200;
// Variables
private List<String> logsList;
private Context appContext;
// class initialization is called first time you call getInstance
private static LoggerSingleton instance ;
public static LoggerSingleton getInstance() {
return instance;
}
public static void initLoggerSingleton(Context context){
if(instance==null)
instance = new LoggerSingleton(context);
}
// Constructor
private LoggerSingleton(Context context) {
logsList = new ArrayList<String>();
appContext = context;
SharedPreferences settings = appContext.getSharedPreferences(LOG_FILE, Context.MODE_PRIVATE);
try {
JSONArray jsonArray = new JSONArray(settings.getString(LOG_FILE, "[]"));
for (int i = 0; i < jsonArray.length(); i++)
logsList.add(jsonArray.getString(i));
} catch (Exception e) {
e.printStackTrace();
}
}
public String getLogs() {
return logsList.toString();
}
public void appendLog(String newLog) {
String currentDateandTime = Utils.getMyDateTime();
newLog = currentDateandTime + "_" + newLog;
Log.d(appContext.getString(appContext.getApplicationInfo().labelRes), newLog);
logsList.add(newLog);
while (logsList.size() > MAX_LINES)
logsList.remove(0);
JSONArray jsonArray = new JSONArray();
for (int i = 0; i < logsList.size(); i++)
jsonArray.put(logsList.get(i));
SharedPreferences settings = appContext.getSharedPreferences(LOG_FILE, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();
editor.putString(LOG_FILE, jsonArray.toString());
editor.commit();
}
}
after that you can access your singleton from activity or different class
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LoggerSingleton.getInstance().appendLog("String");
}
}
best way to save you data on Activity call onStop and read onStart/onResume
when activity call onDestory method os market your application to be removed from processes and remove from os if os need more momory
about saving you arrayList in sharedPref Saving Serializable Objects List into sharedPreferences