0

I am quite new to Android and I have a scenario while developing an app in Android which I can't figure out what method I should use to save and access my preferences between different activities, widgets, background services, broadcast receivers and etc ...

I believe there must be a simple built in way for this, but after searching for a while already, I just came across some wired articles which I can't understand at all without pointing out to a simple method to help my situation.

Here is my scenario:

  • I have an app which can have multiple activities, multiple widgets, multiple background services and also multiple broadcast receivers (I understand that we use a receiver for a widget as well) ...
  • Any of the objects mentioned above might be present or not depending on the current situation, for example a widget can be present in the home screen while no activities or background services are running, or a background service might be running while no activities are running at the moment and this goes on for all other possible situations in the same way ...
  • It is also possible that while a widget is present in the home screen, an activity is also running and there might even be a service running as well and some.
  • Services might be running on a separate thread.

So based on these conditions what is the standard method used in Android to achieve my goal of having data saved and accessed between them?

My normal approach is using SharedPreferences like this:

SharedPreferences p = getSharedPreferences("Settings", MODE_PRIVATE);

But the first problem is that SharedPreferences needs a Context and I don't have that in a service for example. Even if I somehow pass my main activity's Context to the service, what happens when that activity is finished or killed while the same service is still running in a separate thread?

So please if anyone can guide me towards the correct way of saving and accessing data in a such scenario or a way to have an always valid Context inside services and widgets and etc without any need to an activity being present, so calling for example getSharedPreferences("Settings", MODE_PRIVATE) from that Context always returns me same SharedPreferences object which I can work with the data stored in it from other sources, I would be very happy. Thanks!

Onik
  • 19,396
  • 14
  • 68
  • 91
Night2
  • 1,168
  • 9
  • 18
  • `Service` is [`Context`](http://developer.android.com/reference/android/content/Context.html) – Onik Oct 17 '15 at 20:55
  • @Onik: Do you mean I must have a `this.getContext` in a service or `this.getSharedPreferences`? – Night2 Oct 17 '15 at 21:08
  • Yes, that's what I mean. – Onik Oct 17 '15 at 21:12
  • @Onik: I tested it and you are correct, I have getSharedPreferences inside a service, but what happens when the service is in a separate thread? Will `getSharedPreferences(x)` be same as the `getSharedPreferences(x)` in my activity in the other thread? – Night2 Oct 17 '15 at 21:46
  • _"but what happens when the service is in a separate thread?"_ It's ok, cause it is still within same process and all the app's resources belong to the proccess no matter what thread they're reached from. – Onik Oct 17 '15 at 21:52
  • @Onik: After some tests today, Your comments and the answer you deleted helped me a lot to achieve what I needed, since you deleted the answer and suggested a possible duplicate which is mostly similar to my case, I did accepted it. Thanks ... – Night2 Oct 18 '15 at 22:05
  • Good for you! I was going to edit my answer today, which would have demanded a lot of efforts taking into consideration such a fundamental for Android problem as Context. Then after looking at all those bearded posts regarding the problem I came to understanding that I wouldn't have said better than it's already said... Closing the question, as I thought, would help you refer to the duplicate (bearded) question (and the other related to it) and find the right answer. If I was mistaken, sorry... :) – Onik Oct 18 '15 at 22:20
  • You have been correct, even-though the question in http://stackoverflow.com/questions/9109073/application-context-for-sharedpreferences isn't exactly like mine, the answers there cover what I asked. – Night2 Oct 18 '15 at 22:37

1 Answers1

0

You can access the SharedPreferences using the application context instead of the activity context.

getApplicationContext().getSharedPreferences("Settings",MODE_PRIVATE); 
  • Is this accessible anywhere? Can I use it like this? `public final class x extends Service { public void onCreate() { getApplicationContext()... } }` and like this `public class x extends BroadcastReceiver { public void onReceive(){ getApplicationContext()... } }` ? – Night2 Oct 17 '15 at 21:07
  • I was reading this answer: http://stackoverflow.com/questions/10641144/difference-between-getcontext-getapplicationcontext-getbasecontext-and says that getApplicationContext() returns the Context for the current process, so what if I use this code in my service on create? `HandlerThread thread = new HandlerThread("ServiceStartArguments"); thread.start();` I believe it's a new thread, is it still counted as same Context with the rest of the application? – Night2 Oct 17 '15 at 21:13
  • You can use getApplicationContext in the Service and onCreate but if you want to acces the context from anywhere, just define a WeakReference to the Application and then get the application context from the weak reference like this. `public class receiver extends BroadcastReceiver { final WeakReference app = new WeakReference(); @Override public void onReceive(Context context, Intent intent) { app.get().getApplicationContext().getSharedPreferences` – Vladimír Gašpar Oct 17 '15 at 21:13
  • In order to use the context in a separate process, you need to pass it in a custom thread constructor. Btw. using static context is not best practice and is not recommended due to possible memory leaks. In most cases you should use WeakReference to retrieve the context anywhere. – Vladimír Gašpar Oct 17 '15 at 21:28
  • I'm a bit confused now, I will give these a try today and see what happens when my service runs in a separate process. I must first learn what WeakReference is because never heard of it before and then test it. If I get it to work I will come back to accept the answer. – Night2 Oct 17 '15 at 21:44