I was wondering if I have 2 activities that needs to update and access the same object . What would be the best way to do it? Should I use Application class? Or perhaps Static variable.. Etc?
Another option I can think of is putting it in a base class that both activities inherit. I will initialize the object from shared preferences during OnResume
If your object holds some kind of preference value, don't put it into a super-class. Make it static and/or use the singleton pattern and separate it from your application logic. This provides you with a more modular structure that will be easier to work with. The application class is probably overkill; singletons do the job most of the time. (The Android docs simply states: "There is normally no need to subclass Application.")
You can add it to a super-class, if it is a logical part of it though.
Don't forget to synchronize your object if it's going to be accessed by another/several thread(s).
There are different method to perform such requirement. Singleton is one of them. The other one is extending the application class. If you want a reference outlining all of these methods please see:
What's the best way to share data between activities?
Related
The only way that I see is to use a static variable, but it's not okay as I want to keep the ability to start multiple Activites.
In my case, I want to keep a reference of Dagger 2 Component.
It will provide objects like Navigator. I can't just store it into Bundle.
For now, I can't use Retain MainFragment instead of MainActivity because of this bug.(I'm at 23 API level)
Is there any Retain Activity implementation?
Huh, well you have two built in solutions in android to fix this problem:
1) If the object is serializeable or parcelable you can override onSaveInstanceState() and read the value out in onCreate. Here are the google developer docs for the specifics on that.
2) If your object is not serializable you can instead override onRetainNonConfigurationInstance() and return that object. You can then get the object back in onCreate. Look at this SO post for how to use this approach (don't persist your activity though! persist the object.). The drawback of this is that you can only persist one object at a time.
I have a more in depth write up of these two approaches and third, declarative approach that you can roll. It relies on onRetainNonConfigurationInstance and allows you to use annotations to declare what variables in your activity should be persisted. check it out here. That said, I wouldn't recommend using this unless you have more than one non-serializeable/parcelable object to persist.
Edit: clarified point that you shouldn't persist your whole activity using onRetainNonConfigurationInstance().
May be its simple question, may be its repeated question, this question s not for upvote and all.
I just want to pass my object from one activity to second and second to third activity. I know there are a lot of ways using shared preferences, Intent bundle from one to another activity.
The reason I want to know that why I can't use an object globally for all my activities and if I can how it is possible?
Thanks
There is a handful of ways in which you can achieve this.
Using a bus/listener:
https://github.com/greenrobot/EventBus
https://square.github.io/otto/
Using the application class (ready the first answer carefully, there are caveats):
How to declare global variables in Android?
And using utility classes with static methods.
Also, if you are have more than one fragment running at the same time, you can create your own interfaces and implement them where you need to receive the information.
I'm new to Android (and Java) and was trying to find out where to store my global variables that I need in my various Activities, Fragments, etc. so I can easily access them, as well as saving and restoring them when the app is paused (a process that not yet fully understand, but that is not my question).
So the general consensus seems to be to use Singletons by extending Application (like described here).
Now that I played around some more I was wondering what is the reason against declaring variables in the main activity (e.g.final static int myVariable) and then accessing the variable trough MainActivity.myVariable? What is the downside?
Thank you in advance!
First, consider to design your app without needing global variables in the first place. Using global state variables might seem like an easy solution at first, but will complicate testing and maintenance later.
If you absolutely must, the application class is the correct place because it's lifecycle is your application's lifecycle. You can also use regular member variables instead of statics.
If you store variables in an activity class as static variables, the downsides include but are not limited to:
Loading another activity class needs to load all the code in the main activity as well.
Unnecessary dependency from activity to another, creating increased coupling.
statics are harder to mock/inject for example in a testing setup. A thin application object with member vars is easier to mock.
You can make a class that is subclass of Application, and scope of this class will be application wide, so you can access variable globally ( across the activities/fragment)
here you will get related info
there is no downside declaring your global variable as static unless the variable is bound to Context...
it is bad way to maintain static reference for Context (like Activity, Service), Views, Drawables and application Resources...
and some one said in SO (I didn't remember), Android will clear static memory in low memory situations...
For example if you are in "FirstActivity" that calls "SecondActivity", using startActivityForResult, to add a Product do a list, in "SecondActivity" you can CANCEL or ADD this product, if you ADDED it you whant to refresh the Product's list in "FirstActivity" so in "SecondActivity" you can use a "private static final int ADDED = 1" and a "private static final int CANCELED = 2" and pass one of this attributes in the setResult's method of "SecondActivity", before call the finish method, in FirstActivity's "onActivityResult" method you can verify if the "resultCode" is "SecondActivity.CANCELED" or "SecondActivity.ADD" and performe the list's refresh or not.
Just an example..
You can use Application's class (OS save variable in memory while app not destroy) or SharedPreferences (OS save variable to file permanent).
Suppose I have an activity MyMainActivity, let's say complex enough with a bunch of code.
From another activity, to access a public variable or a method I instanciate :
MyMainActivity ma = new MyMainActivity();
ma.editVariableMethod();
String example_variable = ma.public_examplevariable;
When I instanciate MyMainActivity ma, is it like creating the hole activity again and storing everything from MyMainActivity to memory, and that way it takes the same amount of memory it would take if I was starting MyMainActivity, or is it just a link which permits to edit variables from MyMainActivity?
You can't instantiate an Activity. The framework has to take care of it. If you want to use public methods either make them static OR get a reference to a valid instance of the activity object.
Edit:
As Squonk pointed out, depending on your use case, it might be a better idea to just extract the shared logic to another new class, at least until you know what you're doing. Giving "full access" to internal variables or even methods in an Activity might seem to work, but it's very likely NOT the right approach.
It is a bad practice to share memory-resident objects between objects in Android, no matter what the objects are. Android won't ensure that it will work. There are alternatives available for most use cases. In the particular case of "accessing a public variable" in another Activity, you can call startActivityForResult(), or ensure that your Activities store data they want to "share" in SharedPreferences, etc.
If you have two or more Activities that use the same method, you should first consider if the class needs to be abstracted into a separate object. Ideally, Activities should be frameworks that delegate to POJOs.
I'm working with SaxParser to parse an xml. The problem is, I have a few screens or activities coded. At the moment, every time I transition to the new activity from a button press for example, the new activity needs to then parse the xml all over again, so it can populate the screen with the specific content.
Is there a way in which I only parse the xml once through the life of the program?
Thank you.
Sure, just parse it once and store what you want to remember in variables.
More completely, you would probably create a class (or classes) classes that represent with properties the same information that is in the xml document. A constructor of the class would take the xml as an argument, parse it, and populate the properties.
Hope this helps.
Sometime earliear I faced the similar problem the problem is that android only allow some of generic datatypes to be sent across activities and if your datatype is not generic then the only solution that I came across it make it public and static
Basically you want a global data to be shared across activities. Then either you can make it static or just create a singleton class and use it across activities. In this singleton class you can store parsed data.
In android there is facility for extending Application class and declaring it manifest file.
So, in any activity you can do getApplication() and access the single instance of that class.
Again this will be similar to Singleton class.
The Application Framework FAQ has a discussion about how to share data structures across activities. Since each activity usually has its own process, it isn't quite as simple as declaring a singleton object.