In my Android project I have an Activity and a Widget (Broadcast Receiver). Both have a simple button. When either of the buttons is clicked, the same action should be executed:
First of all, a Boolean variable should be set to it's opposite value (true to false, false to true). This Boolean should be stored independently from both the Activity's and the Receiver's life cycles.
Then, depending on the Boolean's old state, one of two methods should be executed to query a SQLite Database.
I need something like a Singleton Activity, which has its own Shared Preferences and methods and can be called from various Activities / Receivers.
What would be the best way to implement something like this?
Doesn't sound like anything you want to do requires an activity. I would just write a POJO singleton with a private constructor and a static getInstance() method that returns a reference to a private static instance of the class itself, after initializing it if needed.
Then you can have an instance method that toggles the variable and fires off an AsycTask or whatever to do your query. The state of the boolean can be stored in a private instance variable, or persisted to SharedPreferences depending on how long it needs to be retained.
Related
I have a fragment which contains a RecyclerView and sets it up with an Adapter separated in an own class.
In the fragment class I have a private boolean member which indicates whether the application is in "two pane" mode or not. This member gets updated in the onActivityCreated method.
I gotta use this variable in the adapter.
Previously the classes were nested, so I could directly access it. Now it is in another scope.
I have two ideas:
1. Simply make the member public and static (seems a little bit unprofessional because I don´t want it to be changed from outside)
2. Use an own NotifyDataChanged class to which both the fragment and adapter can subscribe.
What is the best practice doing this in android?
Can't you place the boolean flag in the Activity and pass context in the Adapter's constructor, then check the flag's state through context in where you need to use it?
I have activity that run and do its work, and then run a service (that will not finish when the activity finish.)
All is ok.
My question: the service uses values that declared in the activity class as static public, does these values reset when the the activity finish and the service continue working and using them?
What happens to these values when the activity start again.
According to Android document
How do I pass data between Activities/Services within a single application?
A public static field/method
An alternate way to make data accessible across Activities/Services is to use public static fields and/or methods. You can access these static fields from any other class in your application. To share an object, the activity which creates your object sets a static field to point to this object and any other activity that wants to use this object just accesses this static field.
I think static will remain in the memory as long as the onDestroy() of the activity is not called. Once it is called static members will be removed from memory.
If you need to persist your data then you can use sharedprefrences.
Activity/Service – inherit from ContextWrapper which implements the same API, but proxies all of its method calls to a hidden internal Context instance, also known as its base context. Whenever the framework creates a new Activity or Service instance, it also creates a new ContextImpl instance to do all of the heavy lifting that either component will wrap. Each Activity or Service, and their corresponding base context, are unique per-instance.
I have defined a global variable inside an activity, this variable changes depending on the button user has pressed.
If I go outside of my app UI and come back by holding the home button which shows the list of recent apps, then my variable keeps its state, but if I run my app again by pressing the app aicon the variable state is gone.
Is there a way to keep the state of the variable?
You can save the variable's value during the onSaveInstanceState() callback. Then you use the "icicle" parameter that is passed to and onCreate() to restore the value. You might be interested in reading Managing the Activity Lifecycle.
Also note that Java has class variables and member variables but not global variables.
As what #Code-Guru says, you could use onSaveInstanceState() to save variable's value.
Another simple way to do is to create a static member in a static class to store the variable. The static class exists as long as the app is in the memory.
You can consider to use shared preferences This class is used to store and retrieve simple data.
A few days ago I've discovered that singleton can become anti-pattern in Android. My singleton (class with private constructor and instance stored in static field) was deleted (instance was deleted despite the fact other activities were still using this singleton (via getInstance() method) so another instance had to be created ) because Activity from which it was first invoked was deleted (after invoking finish for only this one activity).
I've read already how this problem can be resolved however I've also just read "Effective Java". There is said that "Single-element enum type is the bast way to implement a singleton".
So now I'm wondering what would be the lifecycle of singleton created this way in Android application? Would it be the same like in case of "standard singleton implementation" so after destroying activity from which it was invoked the first time it will be destroyed (even if it used also in other activities)?
I'm not asking about proper android singleton implemenation or the singleton pattern itself (is it pattern or anti-pattern etc) but I'd like to know what be the lifecycle of such enum singleton object and when it will be destroyed.
In all cases, the classes you use are tied to the ClassLoader that loaded them. This is true in Java in general, not just Android. Android will isolate activities by using new ClassLoaders each time -- at the least, it doesn't promise it won't, and it does as far as I can tell.
Any singleton, or other class-level state, is tied to the Class which is tied to the ClassLoader. This is why your state "disappears"; it's actually that your calling code is seeing a new Class in a new ClassLoader.
So, your enum-based trick, or anything else along these lines, would have exactly the same behavior. You just can't "persist" activity information this way. You can and should write to a SQLite DB. You could probably stash it in the SharedPreferences too.
The application object is a good location to store information which needs to be accessible to various activity or service instances. You can retrieve it like this (where this is an Activity or Service):
private MyApplication app;
in onCreate(...){
...
this.app = (MyApplication) this.getApplication();
...
}
Remember to set the name also in the manifest:
Set the attribute "name" of the "application" tag:
The value is the path to the class relative to the package of your app.
The application object is created when the app is started, you can initialize like in an activity or service in it's onCreate() method.
One thing to remember: The application object can survive closing your "last" activity. In this case you may get the same application object with the state from the previous interaction with your app. If this is a problem you must somehow detect the initial start of your app (e.g. using a special launcher activity without UI, which initializes the application object and then starts a new intent.
BTW, the same may happen with singletons if they have not yet been lost to garbage collection.
My secure singleton implementation is like that:
I create a singleton class which has an attribute of boolean 'didReceiveMemoryWarning';
public class SingleTon(){
public boolean didReceiveMemoryWarning = true;
...
...
}
In application first screen(It is exactly first launch screen)(I have a splash screen that is visible 3 sec)
SingleTon.getInstance().didReceiveMemoryWarning = false;
And in every Activity's onCreate() method, check this boolean data,
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(SingleTon.getInstance().didReceiveMemoryWarning){
{ Load your data from local to your SingleTon class,
because your app was released by OS};
}
}
it is my implementation.
I have a bug in my code that made me think I don't fully understand the Android Lifecycle. Yes, I have read all the docs and looked at the diagrams, but they seem to talk only about when to save data, when the activity may loose focus or get killed. However, my question is if I don't need to save state, what happens to the variables & their stored values? I expected them to be destroyed to, but a bug in my code seems to indicate otherwise.
In my case here is what happened. I have an activity that launches a custom view (no xml, I just draw bitmaps on the screen in my custom view). The only variable I currently have in my activity is just a variable for my view: GameView gameView;
Now in my view, I declare several bitmaps, simple int and float variable to deal with drawing and on touch events and I have one array of objects that contain small bitmaps, coordinates of each objects and a few other things. One of the variables in my class for this object, is a static variable that represents the current count of how many objects their are. I did it this way, so the instantiation of the objects causes it to track how man objects their are, instead of tracking this outside the object's class.
I expected the static variable to stay the same value across all objects, but I also expected this variable to be destroyed along with all the other variables and objects of that Activity's view once onDestroyed was called for that Activity. However, that doesn't seem to happen. When this Activity is launched again, this static variable still contains its previous value from its last run - even though onDestroyed was called.
Now my question is NOT how to fix this (I can write code differently to fix this bug), but I would like to understand why this happens with this static variable, since it isn't global to the whole application, it only exists inside that Activity's view? Also, this makes me wonder about the rest of the variables in that view - are they destroyed and their memory released or at least their values no longer available the next time the activity is called or do I need to do this myself - even though I didn't need to save any of this state data?
Thanks for any insight into this.
onDestroy is an instance method and any memory it releases (or allows the garbage collector to release) will be of the corresponding instance. Activities are not singleton; there can be more than one instance of an Activity.
Static variables are class variables and are accesible to all instances of that class. They are initialized when the class is loaded, not when each instance of the class is created.
Please see Understanding Instance and Class members for more info. An excerpt:
Sometimes, you want to have variables
that are common to all objects. This
is accomplished with the static
modifier. Fields that have the static
modifier in their declaration are
called static fields or class
variables. They are associated with
the class, rather than with any
object. Every instance of the class
shares a class variable, which is in
one fixed location in memory. Any
object can change the value of a class
variable, but class variables can also
be manipulated without creating an
instance of the class.