Passing custom objects between activities? - java

How do I pass custom objects between activites in android? I'm aware of bundles but I can't seem to see any functionality for this in them. Could anyone show me a nice example of this?

You should implement Parcelable interface.
Link to documentation.

Using Parcelable interface you can pass custom java object into the intent.
1) implement the Parcelable interface to your class like:
class Employee implements Parcelable
{
}
2) Pass the Parcelable object into the intent like:
Employee mEmployee =new Employee();
Intent mIntent = new Intent(mContect,Abc.class);
mIntent.putExtra("employee", mEmployee);
startActivity(mIntent);
3) Get the data into the new [Abc] Activity like:
Intent mIntent = getIntent();
Employee mEmployee = (Employee )mIntent.getParcelableExtra("employee");

a Parcel MIGHT solve your problem.
think of a Parcel as an "array" (metaphorical) of primitive types (long, String, Double, int, etc). if your custom class is composed of primitive types ONLY, then change your class declaration including implements Parcelable.
you can pass a parcelable object thru an intent with no difficulty whatsoever (just like you would send a primitive-typed object). in this case i have a parcelable custom class called FarmData (composed of longs, strings and doubles) which i pass from one activity to another via intent.
FarmData farmData = new FarmData();
// code that populates farmData - etc etc etc
Intent intent00 = new Intent(getApplicationContext(), com.example.yourpackage.yourclass.class);
intent00.putExtra("farmData",farmData);
startActivity(intent00);
but retrieving it may be tricky. the activity that receives the intent will check if a bundle of extras was send along with the intent.
Bundle extras = getIntent().getExtras();
FarmData farmData = new FarmData();
Intent intentIncoming = getIntent();
if(extras != null) {
farmData = (FarmData) intentIncoming.getParcelableExtra("farmData");// OK
}

Given an object PasswordState that implements Serializable throughout the object tree, you can pass this object to anther activity as in:
private void launchManagePassword() {
Intent i= new Intent(this, ManagePassword.class); // no param constructor
PasswordState outState= new PasswordState(lengthKey,timeExpire,isValidKey,timeoutType,"",model.getIsHashPassword());
Bundle b= new Bundle();
b.putSerializable("jalcomputing.confusetext.PasswordState", outState);
i.putExtras(b);
startActivityForResult(i,REQUEST_MANAGE_PASSWORD); // used for callback
}

One simple way to pass an object between activities or make a object common for all applicattion, is create a class extending Application.
Here is a example:
public class DadosComuns extends Application{
private String nomeUsuario="";
public String getNomeUsuario() {
return nomeUsuario;
}
public void setNomeUsuario(String str) {
nomeUsuario = str;
}
}
In all your others activities, you just need instantiate one object "DadosComuns", declarating as a Global Variable.
private DadosComuns dadosComuns;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//dados comuns
dadosComuns = ((DadosComuns)getApplicationContext());
dadosComuns.setNomeUsuario("userNameTest"); }
All others activities that you instantiate dadosComuns = ((DadosComuns)getApplicationContext()); you can acess getNomeUsuario() == "userNameTest"
In your AndroidManifest.xml you need to have
<application
android:name=".DadosComuns"

Related

How to get Intent values non Activity Class in Android

I am new to Android. I have a base Activity class (MainActivity.java) which extends Activity. So I can initialized Intent here.
MainActivity.java
Intent myIntent = new Intent(MainActivity.this, ConnectionClass.class);
myIntent.putExtra("ServerName", ServerName);
startActivityForResult(myIntent, 1);
In connectionClass.java I have a class ConnectionClass which doesn't inherited. But I want to access the values from MainActivity.java. So this class Doesn't inherited Activity & onCreate Method. But I need to access the values from MainActivity.java to ConnectioClass.java
ConnectionClass.Java
public class ConnectionClass {
Bundle bundle = getIntent().getExtras();
String ServerName = bundle.getString("ServerName");
}
How can I do this?
I don't know if the "ServerName" is fixed value, or varies each time, or it has a kind of pool of values. If it's the first or third case, I suggest you to use SharedPreferences. It's a relatively small key-value data storage. You can save data in it and it will be permanent in your app once stored unless deleted. So you can save data in MainActivity, and fetch the value in a class wherever you want.
You can find tutorial here : https://developer.android.com/training/basics/data-storage/shared-preferences.html
you can pass the servername to the class when you are instantiating a new object from ConnectionClass in your activity like below
public class ConnectionClass {
String serverName;
public ConnectionClass(String serverName){
this.serverName=serverName;
}
}
then in your activity you have something like:
Bundle bundle = getIntent().getExtras();
String ServerName = bundle.getString("ServerName");
ConnectionClass connection=new ConnectionClass(ServerName);

Passing Data Between Activities in Android App

Hey I am pretty new to making android apps and I understand that the easiest way to pass data between two activities is through an intent.
In one of my classes (EventOptions.java), I call this line of code:
Intent i = new Intent(EventOptions.this, PhotoFetcher.class);
i.putExtra("imageArray", imageIDs);
startActivity(i);
imageIDs is a string array
In my PhotoFetcher class, I want to set a string array called imageIDs to the imageIDs string array that I am passing through the intent.
I want to set images as a global variable in my class:
public class MainActivity extends Activity implements View.OnClickListener{
Intent it = getIntent();
String[] imageIDs = it.getStringArrayExtra("imageArray");
...
}
This crashes my app however. Is this not allowed? And if so, how can I fix it? Thanks in advance!
Need to call getIntent() in a method instead of at class level. call it inside onCreate :
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
// get Intent here
Intent it = getIntent();
String[] imageIDs = it.getStringArrayExtra("imageArray");
}
if I want to use the imageIDs array in another public class defined
in my PhotoFetcher class, do I need to call it again?
To get imageIDsin PhotoFetcher class either declare String[] imageIDs as global variable or pass imageIDs using PhotoFetcher class constructor
You have to use putStringArrayListExtra. You can convert your String[] to an ArrayList first.
Like so
ArrayList<String> arrayList = new ArrayList<String>(Arrays.asList(imageIDs));
Intent i = new Intent(EventOptions.this, PhotoFetcher.class);
i.putStringArrayListExtra("imageArray", arrayList);
startActivity(i);
And then you can fetch it like you do, preferably in onCreate or after that call.
Intent it = getIntent();
ArrayList<String> imageIDs = it.getStringArrayListExtra("imageArray");
Share data without persisting to disk
It is possible to share data between activities by saving it in memory given that, in most cases, both activities run in the same process.
Note: sometimes, when the user leaves your activity (without quitting it), Android may decide to kill your application. In such scenario, I have experienced cases in which android attempts to launch the last activity using the intent provided before the app was killed. In this cases, data stored in a singleton (either yours or Application) will be gone and bad things could happen. To avoid such cases, you either persist objects to disk or check data before using it to make sure its valid.
Use a singleton class
Have a class to whole the data:
public class DataHolder {
private String data;
public String getData() {return data;}
public void setData(String data) {this.data = data;}
private static final DataHolder holder = new DataHolder();
public static DataHolder getInstance() {return holder;}
}
From the launched activity:
String data = DataHolder.getInstance().getData();
Use application singleton (I would recommend this)
The application singleton is an instance of android.app.Application which is created when the app is launched. You can provide a custom one by extending Application:
import android.app.Application;
public class MyApplication extends Application {
private String data;
public String getData() {return data;}
public void setData(String data) {this.data = data;}
}
Before launching the activity:
MyApplication app = (MyApplication) getApplicationContext();
app.setData(someData);
Then, from the launched activity:
MyApplication app = (MyApplication) getApplicationContext();
String data = app.getData();
ρяσѕρєя K hit the nail on the head, you're running a method where constructors and fields go. To make the variables (the imageIDs) global, it's quite simple and there are a few ways of doing it. Declare them outside any method, and then assign them in your onCreate or onResume (which will always be called).
Try this:
public class MainActivity extends Activity implements View.OnClickListener {
//global variable
String[] imageIDs;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// get Intent here
Intent it = getIntent();
imageIDs = it.getStringArrayExtra("imageArray");
}
}

How to pass an object without intent

Currently I am able to pass an object called Exhibit to another Activity by putting it into putExtras and starting the intent. Now, what if I want to pass the object to another object?
For example I send like this:
public void onListItemClick(ListView parent, View v, int position, long id) {
Intent i = new Intent(this, ExhibitOpen.class);
Bundle bundle = new Bundle();
bundle.putSerializable("MyClass", (Serializable) exhibits.get(position));
i.putExtras(bundle);
startActivity(i);
}
Then I receive:
Intent i = getIntent();
dene = (Exhibit)i.getSerializableExtra("MyClass");
Here you can see that I am passing exhibits.get(position) to certain class and start the class as new activity, then the new activity receives it. So, how can I pass the object to another class (not this class) without starting it?
Thanks a lot!
If you don't want your object to be persisted during app launches, you can just set it as a static instance variable of your application class:
public class MyApp extends Application {
private static Exhibit sExhibit;
public static void setExhibit(Exhibit exhibit) {
sExhibit = exhibit;
}
public static Exhibit getExhibit() {
return sHexhibit;
}
}
// To set the object:
MyApp.setExhibit(myExhibit);
// To retrieve it
Exhibit myExhibit = MyApp.getExhibit()
If you don't want to extend your application, you can just do it in any class, or in your Exhibit model, wherever it would make the more sense.
If you want it to persist in between app launches and it's serializable, I would use the Shared Preferences to store it: http://developer.android.com/guide/topics/data/data-storage.html#pref
You can just call a method on the object:
otherObject.someMethod(dene);
Please check this LINK1 , LINK2 and LINK3

How to use getIntent() in a class that does not extend Activity?

I am trying to pass a String from a class "Play" which extends Activity by using:
Bundle data = new Bundle();
Intent i = new Intent(Play.this, Receive.class);
String category;
data.putString("key", category);
i.putExtras(data);
Then, the "Receive" class which is a non Activity class and does not extend Activity will receive the String from "Play".
But when I try to receive the data using this code:
Bundle receive = new Bundle();
String passed;
receive = getIntent().getExtras();
passed = receive.getString("key");
I get an error on the word "getIntent()" and suggests me to create a method getIntent().
What is the possible solution to this problem?
THANKS!
Intent is not nessesary here. You can just do something like this:
Play.class :
public String getCategory() {
return category;
}
and in Receiver.class :
Play playObject = new Play();
passed = playObject.getCategory();
Or you can use static field as pKs mentioned but it's not always a good pattern.
You should use a public static variable and use it to store data and fetch data from other class.
As intents don't work without extending Activity class in Android.
In your case , it would be like.
public static category="some category";
To access in another class ,
String dataFromActivity=NameOFClassWhereCategoryIsDefined.category;
You cannot getIntent(); from within a class that does not extend Activity. As Sprigg mentioned you would have to use other means of communication between the classes.

How do I share variables between classes?

Say I am making something like a quiz, and I have a counter to show the number of questions that have been answered correctly. When one question is correctly answered, and a new screen(Activity) is shown, how do I carry over the number to the next screen?
When you say screens do you mean Activities? Then you probably want to pass them via extras in your intents.
Activity 1:
int score;
...
Intent Intent = new Intent(...);
intent.putExtra("score_key", score);
startActivity(intent);
Activity 2's onCreate():
int score;
...
Bundle extras = getIntent().getExtras();
// Read the extras data if it's available.
if (extras != null)
{
score = extras.getInt("score_key");
}
You can send numbers, strings, etc in a bundle with your intent.
Bundle b = new Bundle();
b.putInt("testScore", numCorrect);
Intent i = new Intent(this, MyClass.class);
i.putExtras(b);
startActivity(intent)
you can also put StringArrays and a few other simple vars
One of this way you can share your data among whole project,
public class mainClass
{
private static int sharedVariable = 0;
public static int getSharedVariable()
{
return sharedVariable;
}
}
From the other class/activity , you can access it directly using classname and . (dot) operator. e.g. mainClass.getSharedVariable();
A good practice for storing variables across Activitiys is using a own implementation of the Application Class.
public class MyApp extends android.app.Application {
private String myVariable;
public String getMyVariable() {
return myVariable;
}
public void setMyVariable(String var) {
this.myVariable = var;
}
Add the new Class in the Manifest.xml inside the application tag:
<application android:name="MyApp" android:icon="#drawable/icon" android:label="#string/app_name">
Now you can manipulate the variable in every Activity as follows:
MyApp ctx = (MyApp)getApplicationContext();
String var = ctx.getMyVariable();

Categories