Sharing Variables Across Different Activities In Android Studio - android

I Have an Activity called Main2Activity, and it consists of a variable "double result1 " which is set equal to an expression. It looks like this:
double result1 = n1 * 2 - 29; (Where n1 is an input given by the user)
I'm trying to use this variable in another class called MainActivityEnd. I tried this:
double finalResult = Main2Activity.result1 * 4;
When I print result1 in Main2Activity using setText it prints the correct value.
But when I print finalResult in MainActivityEnd using setText It always prints 0.0
Is there a reason for this?
Thanks for the help!

If activities are in the same flow, you should use the following Android way - intents. Simply put, Intent is Android's way of changing values between activities when they are launched in sequential order.
So you should do the following in Main2Activity:
Intent intent = new Intent(Main2Activity.this, MainActivityEnd.class);
intent.putExtra("name", variable);
startActivity(intent);
where Main2Activity starts MainActivityEnd. The Intent is filled with the data MainActivityEnd needs, which in this case is "variable".
Afterwards you should catch the Intent in MainActivityEnd onCreate() method like this:
Intent intent = getIntent();
double finalResult = intent.getDoubleExtra("name", 0);
where "name" is the same name that was given in Main2Activity and 0 is a default value if there's wasn't a double value attached to Intent in Main2Activity.
That's the most common usage of this behaviour in Android.

Use Intents or SharedPreferences like other people has already mentioned here.
If however you are planning to put some global logic (like methods) then use Application class.
You can extend Application class like this:
public class YourApplication extends Application {
public double result1 = 29;
}
And then in any in your Activities:
YourApplication app = (YourApplication) this.getApplication();
System.out.printl(app.result1);
Make sure that you named your application class properly, it should be [YOUR_APP_NAME]Application. And also don't forget to put your new application class into the manifest:
<application
android:name=".YourApplication"

Related

How to store global variables using setter and getter in Android?

i am new to android development and i was trying to use a global variable across two activities. So how do i do the same using setter and getter? or is there a better way?
Please do help me!
Thanks in advance!
Sidharth
For global variable :
Use can use SharedPreference, which will save the value till you uninstall the application and can be accessed from anywhere within application using context.
Extend Application class, and declare the global variable inside it and add getter and setter methods.
And in your activity :
YourApplication yourApplication = (YourApplication) getApplicationContext();
yourApplication.setGlobalValue(10);
yourApplication.getGlobalValue();
Create class :
class YourApplication extends Application {
private Integer globalValue;
public Integer getGlobalValue() {
return globalValue;
}
public void setGlobalValue(Integer value) {
globalValue = value;
}
}
The easiest way to do this would be to pass the variable to the second activity in the intent you're using to start the activity:
Intent intent = new Intent(getBaseContext(), SignoutActivity.class);
intent.putExtra("variableKEY", variable);
startActivity(intent)
Access that intent on next activity
String s = getIntent().getStringExtra("variableKEY");
The docs for Intents has more information (look at the section titled "Extras").
From here

How to persist a subset of data from a larger set in Android?

A network call returns a very large json file. However, I just need to use a small portion of this through out the entire app. What is the best strategy on using a small amount of data for several fragments and activities ?
I tried to use shared preferences, but that does not store objects.
For sharing complex data structures or objects, I would extend Application by making a custom sub class. Application object (as the name implies) is accessible to all Activities, even when app transitions from one to another. Below is a very simple example, just to show you the idea. You can modify/adjust that to your needs.
public class MyApplication extends Application {
private X x;
public static void setX(X x) { ... }
public static X getX() { ... }
}
public class ActivityA extends Activity {
...
MyApplication.setX(x);
}
public class ActivityB extends Activity {
...
X x = MyApplication.getX();
}
X can be a collection, data structure, or any object for that matter.
When extending Application, you need to declare it in the manifest. You can find information on how to do that.
Extract the required data from your JSON as a String and then pass it as an extras parameter to the Activities and Fragments that need it:
Intent intent = new Intent(context, SomeActivity.class);
intent.putExtra("YOUR_DATA_KEY", yourJsonString);
startActivity(intent);
and then extract it back again at the Activities and Fragments that need it:
Intent intent = getIntent();
String yourJsonString= intent.getStringExtra("YOUR_DATA_KEY");

passing variable status between classes

I am making a boolean variable value in one class and accessing the status of that variable in another class , on the basis of the boolean variable status my list view shows items,
So my question is
how to create a global boolean varible
how to pass it to another class
how the second class check it
1. Variable in class A
public class A{
public String aClassVar="hello";
}
Using it in Class B
A obj=new A();
String inBClass=obj.aClassVar;
2. To pass data from one Activity to Another Activity you can use Intent remember your Class should extends Activity only than you will be able to pass data by using Intent
Example
Send Data From First Activity using :
Intent i = new Intent(this, SecondClassName.class);
i.putExtra("key", "Value");// key is used to get value in Second Activiyt
startActivity(i);
Receive Data on Second Activity using:
Intent intent = getIntent();
String temp = intent.getStringExtra("key");// usr getStringExtra() If your extra data is represented as strings:
And you Must set Activity Name inside AndroidManifest.xml
like:
<activity android:name="yourPackageName.SecondClassName" />
Let me suggest 3 options.
Do you want to pass a boolean variable between Android Activities? If so, You may want to use a Bundle. Yes, those little things given to Activities on onCreate(). You can pass variables of your own into these, in your case a boolean, with putBoolean() and getBoolean()
Would you prefer using Android's SharedPref? It's an interface for sharing small preferences, like boolean flags, between parts of your app and storing it for later.
Or, you could just implement a singleton class that has the boolean variable and other variables you need to store and check by different classes within your app.
If you just want to access the value of an object or variable in another class, make it Static and then when you need its value, do like
public class tempClass {
public void tempMethod() {
boolean status = myClass.myVariable ; // where myVariable is static boolean varaible of myClass
}
}
But make sure to access the variable after some value is stored in it.
If you want to send the value to another activity then send the value by using intent.
Eg.
Bundle myBund = new Bundle();
myBund.putBoolean(myBool);
Intent intent = new Intent(myClass.this, tempClass.class);
intent.putExtras("myKey",myBund);
startActivity(myBund);

Static Keyword , Reinstallation Required

In my application I have an Activity" Model" in which i get a value 'n' from an edit text , I have declared this value n as static int . So , that i can access it inside any class of the Application.
The problem is that when I restart my application without reinstalling it , the value of 'n' remains the same as it was in the first case . And this affects my output.
I cannot use intent to send values because , the value is accessed randomly in the application even in classes that are not activities.
Can u please tell , where I m wrong.??
package com.integrated.mpr;
import java.io.File;
import android.app.Activity;
import android.app.Dialog;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class Model extends Activity implements OnClickListener{
EditText etPos;
Button bmodel;
static int n;//static variable to be used in other classes
File folder ;
File subfolder;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.inputpage);
etPos = (EditText) findViewById(R.id.etpos);
bmodel = (Button) findViewById(R.id.bModel);
bmodel.setOnClickListener(this);
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch(v.getId()){
case R.id.bModel:
String check = etPos.getText().toString();
String check1 = etNs.getText().toString();
n = Integer.parseInt(check);
Intent openAlternative = new Intent("com.integrated.mpr.ALTERNATIVE");
startActivity(openAlternative);
break;
}
}
}
If i first install my app , and enter value in the edittext as 2 , the value of n =2 ; If second time i run my app without installing it , even if i enter 3 in the edittext , value of n remains 2
Where is the twist??
Kumar,
The behavior you are seeing is the result of using a static member. static members do not require an instance and are therefore set upon first access (regardless of whether an instance was created or not) and stays in memory until Android decides it is no longer valid. In essence, it is doing exactly what it was supposed to. The proper use of static variables is a topic of extensive discussion among veteran and novice programmers alike, but essentially always leads to "be choosy about where and how you use static members".
That said, your need to access this from another component is a common problem, however, and there are a number of ways to solve it. If you need to have each instance have a different value, then it should not be static. Instead you will have to find a way to pass the instance of the Activity.
If each instance need not be different, but the value need to change according to some other parameter, simply find the appropriate place to change the value. If you can access it from anywhere in your application, you may also change it from anywhere in your application.
Solution 1: Passing by Intent
This solution is useful when the information is subject to change and must be sent to another component and the classes that it uses exlusively. You may pass virtually any value via an Intent extra.
openAlternative.putExtra("MyValue", Integer.parseInt(check));
In your responding component, you may retrieve the value by:
Intent myIntent = getIntent();
int n = myIntent.getIntExtra("MyValue", 0); //0 is the default if no value is sent.
From here, you may easily pass the retrieved value to any class being utilized by that component. An example:
MyClass.setN(n);
Solution 2: Storing outside of the LifeCycle
A safer alternative is to move the value to an extended Application. This is not subject to UI or LifeCycle processing.
public class MyApplication extends Application
{
static int n;
}
Adjust your AndroidManifest.xml...
<application android:name=".MyApplication" ... >
<!-- All of your components -->
</application>
Now, you can set the variable this way:
MyApplication.n = Integer.parseInt();
And you can get it by
int myN = MyApplication.n;
This solution has gotten me through many a troubled day. However, it should really be used for non-instance related data.
Solution 3: The REALLY UNSAFE method
This solution only works if you can guarantee a single instance of the component. This requires that singleTask is set. Be very careful with this
Change n to non-static
int n;
Change Activity to Singleton
static private Model myInstance;
In OnCreate, set myInstance
myInstance = this;
Create a getter:
static public Model getStaticInstance()
{
return myInstance;
}
This is unreliable (at best) and can cause huge memory leaks if not managed correctly.
Hope this helps,
FuzzicalLogic

Extending the Intent class ... received ClassCastException

I am attempting to create an enhanced Intent class (I call it DataIntent) by giving it the ability to hold a "payload" of type Object (versus using it's built-in facility for Uri's). DataIntent extends Android's Intent class.
My Activity creates the extended object without any problems and the invocation of the startActivityForResult() goes off without any problems also. But, in my responding Activity when I call the getIntent() method, and attempt to cast it to my DataIntent, I'll throw the ClassCastException.
I realize this is probably a very dumb question - a 1,000 appologies in advance - but does anyone know why I cannot cast it to the DataIntent since that's what was used to start the new Activity, and DataIntent is a child of Intent?
DataIntent dataIntent = (DataIntent)getIntent();
// invoked inside the responding Activity instance - throws a ClassCastException
You can't do that, sorry. You need to place your data inside of the Intent. The Intent object is moved across processes and thus the one you get back is not the same instance as the one you created.
I did the same thing CirrusFlyer. I also looked for the final keyword before I started to implement it. Google should mark Intent class as final.
You can and should extend an Intent, but you must understand the purpose of an Intent.
#1 an intent must be parcelable to support persisting the intent-data across an app restart (collapsed due to memory limitations, trimMemory etc).
#2 Understand that the Intent constructed by the caller, is not the Intent provided to the activity. This is due to item #1. So any object references would be lost and are a bad idea -- it needs to be parcelable remember.
#3 Intents should only contain data-context for the activity (or whatever). So you should not place pages of data into an intent, rather, it should contain ids or keys, or whatever contextual data is necessary to re-obtain the data for the activity (or whatever).
Now... Why should you extend an Intent? For good contracts!
Intents by themselves are terrible contracts, way too loose. Some people create static method helpers but there is a better way.
If an ABCActivity requires "A" "B" and "C" to perform properly. A generic intent cannot describe that, we'd rely on documentation that no one will read.
Instead we can create a ABCIntent whose constructor demands A,B & C. This creates a clear contract on what is required to load the activity. We can do that with a static method, but a an ABCIntent can also provide getters for A B C making it a clean packaged contract for describing requirements to load the activity and how to obtain the data.
There is one caveat, we need a private constructor to construct our ABCIntent from a generic intent to inherit the extras.
public ABCActivity extends Activity {
private ABCIntent intent;
public static ABCIntent extends Intent {
private ABCIntent(Intent intent) {
super(intent);
}
public ABCIntent(A a, B b, C c) {
putExtra("EXTRA_A", A.serialize(a));
putExtra("EXTRA_B", B.serialize(b));
putExtra("EXTRA_C", C.serialize(c));
}
public A getA() { return A.deserialize(getExtra("EXTRA_A")); }
public B getB() { return B.deserialize(getExtra("EXTRB_B")); }
public C getC() { return C.deserialize(getExtra("EXTRC_C")); }
}
#Override
protected ABCIntent getIntent() {
return intent == null ? (intent = new ABCIntent(super.getIntent())) : intent;
}
#Override
protected void onCreate( ... ) {
A a = getIntent().getA();
B b = getIntent().getB();
C c = getIntent().getC();
// TODO: re-obtain activity state based on A, B, C then render
}
}
Notice that we construct ABCIntent from intent.
The ABCIntent inherits the intent extras.
Now you have a nicely packaged class who's job it is to define the contract for the activity and to provide the contractual data to the activity.
If you're a new engineer on the project, there is no way for you to misunderstand how to use this. No docs to read.

Categories

Resources