Is it possible to create a variable in the starting activity (eg : Book class in Activity 1)
and have it available anywhere in the application (eg Book class in Activity 3 , 4 &5) without actually passing it.
I am asking because my xml handler creates a series of objects be it also updates the xml file after any change is made to the object.
You can create a static variable. As long as it's declared with appropriate access (e.g., public) it will be directly available to any activity in the same process. (This will be the default; you need to do extra work to get an activity into a separate process.)
It's common to separate out such global variables into a separate class.
However, be aware that if your app is pushed into the background, there's a chance that the process will be killed off and re-created. In that case, any data stored in static variables will be lost. Alternatives include using SharedPreferences, a data base, or a ContentProvider.
Implement a class, for example with the name GlobalVariables, which extends Application.
public class GlobalVariables extends Application
In your AndroidManifest.xml do this in the application tag:
<application android:label="#string/YourAppName" android:icon="#drawable/YourIcon"
android:name=".activities.GlobalVariables.">
Don´t forget the package path for declaring your class (similar you do for adding activities to manifest file).
Then you can access this class and its variables or methods from everywhere of your application. Do this in the onCreate method of any Activity:
GlobalVariables globalVariables = (GlobalVariables) getApplicationContext();
The Class extended from Application (e.g. our GlobalVariables here) will be created with the start of your app and will be available until the app will be destroyed.
You can have a HashMap or something, else where you can store your desired variable, in the GlobalVariables class. Push the variable from your first Activity into the GlovalVariables and pull it from the second trough getting an instance to the GlobalVariables. Like this (once again):
GlobalVariables globalVariables = (GlobalVariables) getApplicationContext();
Related
I want write dynamically Intent, so I want to write G.currentActivity instead of GSampleActivity.this.
G class extends Application.
I defined G class in application Tag that is before activity Tags:
I don't understand why you need that... Besides, G.currentActivity is null in the shown code
Application class is a Context, so you don't need to store a static field.
Activity class is a Context, so you don't need to grab anything from the Application class.
You can use GSampleActivity.this within startActivity and keeping around static references to the current Activity is very brittle and asking for bugs and memory leaks.
P.S. Use Android Studio
I have an activity that consists mainly of a viewpager. The user can open new versions of that activity with different intents, thus making the data in the viewpagers different. Problem is when I access static variables in other classes from the main activity type, it seems as if it is editing variable values in all open versions of the activity. If I finish() the top activity,the data in the original activity has changed to that of the child activity. What is a way to keep references to static variables with only the current activity?
Thanks!
What is a way to keep references to static variables with only the current activity?
Quite simply - you can't.
In Java when you declare a variable as static in the main body of the class, it is a 'class variable'. This means that all instances of that class share only one variable between them. Consequentially (as you've already found out) changing the value in any instance of the class will change the value for all instances as there is only one 'copy' of the variable.
A golden rule in Android is to NEVER use static variables or methods in Activities.
There are two reasons for this - if your Activity is only ever extended within your ouwn code, then having a static variable or method is pointless and (as you've discovered), it's counter-productive.
The second reason is that static is often used with the public modifier in order to allow an 'all-areas' access to variables and/or methods regardless of whether an actual instance of any given class exists or not - in the case of the class being an Activity, this is a VERY dangerous game to play because of the life-cycle of Activities.
If you have a 'base' Activity which you want to start various instances of but want a common variable they all need to have access to, then simply declare it as...
protected Object myVariable;
...replacing Object with whatever type of variable you want.
Each Activity will get there own instance of myVariable and can change its value without affecting any other instance of the same Activity class.
See the following for Java Class Variables
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'm taking an android class now, so I am somewhat new to android app development.
My first assumption for a Base Activity is that it's Global Variables and it's values would be available to all activities. I have found that it is available to my Main Activity, but not any activities after that.
In the Base Activity I am storing an ArrayList of Objects. I also load data from an xml in there that adds objects to the arrayList. Once in the Main Activity I still have access to that arrayList and it's values. I use it to fill a list. But when I go to the next activity, it knows about the arrayList but thinks it is empty.
Do I need to create methods in the base activity to retrieve the arrayList and to add objects to the array list?
Any help would be appreciated.
Thank you,
Michelle
Global variables need to be declared static. Then they would be accessible from any class. Example:
public class Globals {
public static String myString;
}
Any class can read/write the myString like this:
Globals.myString = "foo";
or
String bar = Globals.myString;
From experience I believe the variables of one activity is only avaliable to the other while the activity is active, which means between onCreate and onDestroy, other then that you will probably get a null pointer exception, what you really should be doing is sending the data, or arrays, along with the intent to the other activity.
I dont think you should be calling on other activities variables, although it is possible as stated above. I believe when the activity has had it's onDestroy method called the objects in the activity are destroyed to and are removed from memory. Destroying anything that they held.
What is this base activity? Does it just extend activity? And then MainActivity is extending Activity as well? Only one activity is usable at any one time, if your doing what I think your doing you should have a service which can provide you with everything over the cycle of the application, just remember to stop it when your done with it.
I've spent a while reading up on this and have yet to find an answer.
I have a few activities all within one app. I'd like to share some data between them that is not suitable for intents or serialized data files. I know I can use the overall Application for this purpose, but I'm not fully understanding how it works.
We'll call my overall application class "MyApplication" and the main activity "MyActivity". I would expect that once the app begins from a cold start, it first instantiates and initializes MyApplication (calling onCreate()) and then goes on to instantiate and start my activity (MyActivity) (which was marked with the intent android.intent.action.MAIN). The logs seem to bear this out.
But... if I try to set the following Activity-wide variable, it gets set to null:
private final MyApplication THISAPP = (MyApplication)getApplication();
This is peculiar because the application definitely exists at this point. (Also, I can't delay setting a final variable til MyActivity.onCreate() gets called - that's disallowed ("The final field...cannot be assigned")).
Note that this works if I don't call THISAPP "final" and I assign it in onCreate(). That of course defeats the purpose of protecting a variable with "final" though, and it seems like it should be possible to do.
So, why isn't getApplication() producing a non-null value before onCreate()? Or is this some strange matter of context? (I've found a vague reference to context not being valid til after onCreate() is done, but would that apply to the parent Application's context as seen from a child Activity? I'd expect the parent to already have that set at that point.)
Edit: to emphasize, I can get this to work if I don't try to use final and if I remember to put the "." before the application name in the manifest (a mistake I made and corrected well-before this I wrote this question). It just isn't clear why getApplication() (or getApplicationContext() for that matter) aren't usable before onCreate() in a child Activity... unless "that's just how it is".
I'd like to share some data between them that is not suitable for intents or serialized data files. I know I can use the overall Application for this purpose, but I'm not fully understanding how it works.
I'd just use static data members as a cache for your persistent store, rather than fussing around with Application. Application gives you little advantage over static data members and has one big cost: there can only be one Application, whereas you can organize your static data members/singletons however you like.
I would expect that once the app begins from a cold start, it first instantiates and initializes MyApplication (calling onCreate()) and then goes on to instantiate and start my activity (MyActivity) (which was marked with the intent android.intent.action.MAIN). The logs seem to bear this out.
Correct.
But... if I try to set the following Activity-wide variable, it gets set to null: private final MyApplication THISAPP = (MyApplication)getApplication();
Of course. The activity object has not yet been initialized. You are welcome to use initializers like this for constants or things you get from static methods (e.g., Calendar.getInstance()) or other constructors (e.g., new ArrayList<Foo>()). Do not call a superclass method an expect it to work at this point, since the constructor chain has not yet been called on the object being instantiated. This is just Java, nothing particular to Android.
Have you done it the following way?
Created a class that implements Application
public class MySuperApplication extends Application
{
public String SomeSetting;
}
Defined which is your Application class in manifest (important!)
<application android:name=".MySuperApplication" android:icon="#drawable/icon"
and then accessed it in your activities
app = (MySuperApplication) getApplication();
app.SomeSetting = "Test";
This should work. It does in my case.
AFAIK, You cannot declare a empty final variable and initialize it onCreate. In java it is initialized during declaring the variable or in the constructor.
THISAPP cannot be initialized to Application object during declaration because the Application doesn't exist during compile time. Because onCreate is not a constructor, you cannot declare a empty final variable and initialize it in onCreate.
Instance variables are created when the object (in this case an Activity object) is constructed. For getApplication() to produce a valid value then the Activity object would have to have been provided enough context (little 'c') at instantiation for this to occur.
The source for getApplication() in Activity.java is just this:
/** Return the application that owns this activity. */
public final Application getApplication() {
return mApplication;
}
Here is where it is set:
final void attach(Context context, ActivityThread aThread, Instrumentation instr, IBinder token,
Application application, Intent intent, ActivityInfo info, CharSequence title,
Activity parent, String id, Object lastNonConfigurationInstance,
Configuration config) {
// other code
mApplication = application;
// other code
}
Since mApplication is not set until after attach is called, it won't be available to getApplication() on instantiation of your Activity.