Get reference to object from another activity - android

EDIT:
This is the method I use to initialize variables after the layout of the activity is loaded in the onCreate() method
private void initializeVariables() {
randomButton = (Button) findViewById(R.id.randomButton);
gameButton = (Button) findViewById(R.id.gameButton);
i = 1;
listIndex = 0;
nameList = PlayersNames.nameList;
villagerBundle = new ArrayList<>();
characters = new ArrayList<Card>();
players = new ArrayList<Player>();
villagerOne = new Villager();
villagerTwo = new Villager();
villagerThree = new Villager();
villagerFour = new Villager();
villagerFive = new Villager();
villagerBundle.add(villagerOne);
villagerBundle.add(villagerTwo);
villagerBundle.add(villagerThree);
villagerBundle.add(villagerFour);
villagerBundle.add(villagerFive);
}
ORIGINAL QUESTION:
I have 2 activities in Android.
In one i create:
public static Villager villagerOne;
villagerOne = new Villager();
Then in the other one I should access to the villagerOne's mAlive variable:
villagerOne.getMAlive();
For reference, these is the Card class:
public class Card {
//Names
public String mCharacter;
//Status
private boolean mAlive;
private boolean mDefended;
private boolean mOwled;
private boolean mLastSavaged;
private boolean mLastLynched;
//Constructor
public Card(){
}
public void setMCharacter(String value){
this.mCharacter = value;
}
public void setMAlive(boolean alive){
this.mAlive = alive;
}
public String getMCharacter(){
return mCharacter;
}
public boolean getMAlive(){
return mAlive;
}
}
And this is the Villager class which extends Card:
public class Villager extends Card {
public Villager(){
mCharacter = "Villager";
}
}

I think if you make the Villager class implement Serializable you could send it with an intent like:
Intent i = new Intent(FirstActivity.this, SecondActivity.class);
Villager villagerOne;
villagerOne = new Villager();
i.putExtra("Villager", strName);
startActivity(i);
And on the second activity you get the results:
Villager villager = (Villager) getIntent.getSerializableExtra("Villager");

Since you declared your villager as static in activity one you should be able to access it from anywhere by
one.villagerOne.getMAlive()
(here I assume the name of the activity class one is one)
Since this solution seems to be controversial I'll tell you why I think it is a good one:
If you pass a copy of the Villager through intent and your Villager gets "killed", the original Villager will be destroyed, why the copies will still be alive. this means you have to communicate to every activity with a copy and tell them to defunct their copy of the villager. Listeners and all.
If you use the reference to the static member, as I suggested, all you have to do is test the reference for null before you call any method:
if( one.villagerOne != null ) alive = one.villageOne.getMAlive();

If you need a copy of that variable, you should pass it in via extras. If you need to access that actual variable- you probably should rearchitect. Data that's needed by multiple Activities shouldn't be owned by any Activity, it should be owned by another data structure that both Activities could reach. For example a singleton Player object which can be queried for its list of cards.

Related

Pass a model class object from a Fragment to another Activity [duplicate]

How can I pass an object of a custom type from one Activity to another using the putExtra() method of the class Intent?
If you're just passing objects around then Parcelable was designed for this. It requires a little more effort to use than using Java's native serialization, but it's way faster (and I mean way, WAY faster).
From the docs, a simple example for how to implement is:
// simple class that just has one member property as an example
public class MyParcelable implements Parcelable {
private int mData;
/* everything below here is for implementing Parcelable */
// 99.9% of the time you can just ignore this
#Override
public int describeContents() {
return 0;
}
// write your object's data to the passed-in Parcel
#Override
public void writeToParcel(Parcel out, int flags) {
out.writeInt(mData);
}
// this is used to regenerate your object. All Parcelables must have a CREATOR that implements these two methods
public static final Parcelable.Creator<MyParcelable> CREATOR = new Parcelable.Creator<MyParcelable>() {
public MyParcelable createFromParcel(Parcel in) {
return new MyParcelable(in);
}
public MyParcelable[] newArray(int size) {
return new MyParcelable[size];
}
};
// example constructor that takes a Parcel and gives you an object populated with it's values
private MyParcelable(Parcel in) {
mData = in.readInt();
}
}
Observe that in the case you have more than one field to retrieve from a given Parcel, you must do this in the same order you put them in (that is, in a FIFO approach).
Once you have your objects implement Parcelable it's just a matter of putting them into your Intents with putExtra():
Intent i = new Intent();
i.putExtra("name_of_extra", myParcelableObject);
Then you can pull them back out with getParcelableExtra():
Intent i = getIntent();
MyParcelable myParcelableObject = (MyParcelable) i.getParcelableExtra("name_of_extra");
If your Object Class implements Parcelable and Serializable then make sure you do cast to one of the following:
i.putExtra("parcelable_extra", (Parcelable) myParcelableObject);
i.putExtra("serializable_extra", (Serializable) myParcelableObject);
You'll need to serialize your object into some kind of string representation. One possible string representation is JSON, and one of the easiest ways to serialize to/from JSON in android, if you ask me, is through Google GSON.
In that case you just put the string return value from (new Gson()).toJson(myObject); and retrieve the string value and use fromJson to turn it back into your object.
If your object isn't very complex, however, it might not be worth the overhead, and you could consider passing the separate values of the object instead.
You can send serializable object through intent
// send where details is object
ClassName details = new ClassName();
Intent i = new Intent(context, EditActivity.class);
i.putExtra("Editing", details);
startActivity(i);
//receive
ClassName model = (ClassName) getIntent().getSerializableExtra("Editing");
And
Class ClassName implements Serializable {
}
For situations where you know you will be passing data within an application, use "globals" (like static Classes)
Here is what Dianne Hackborn (hackbod - a Google Android Software Engineer) had to say on the matter:
For situations where you know the activities are running in the same
process, you can just share data through globals. For example, you
could have a global HashMap<String, WeakReference<MyInterpreterState>>
and when you make a new MyInterpreterState come up with a unique name
for it and put it in the hash map; to send that state to another
activity, simply put the unique name into the hash map and when the
second activity is started it can retrieve the MyInterpreterState from
the hash map with the name it receives.
Your class should implements Serializable or Parcelable.
public class MY_CLASS implements Serializable
Once done you can send an object on putExtra
intent.putExtra("KEY", MY_CLASS_instance);
startActivity(intent);
To get extras you only have to do
Intent intent = getIntent();
MY_CLASS class = (MY_CLASS) intent.getExtras().getSerializable("KEY");
If your class implements Parcelable use next
MY_CLASS class = (MY_CLASS) intent.getExtras().getParcelable("KEY");
I hope it helps :D
implement serializable in your class
public class Place implements Serializable{
private int id;
private String name;
public void setId(int id) {
this.id = id;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Then you can pass this object in intent
Intent intent = new Intent(this, SecondAct.class);
intent.putExtra("PLACE", Place);
startActivity(intent);
int the second activity you can get data like this
Place place= (Place) getIntent().getSerializableExtra("PLACE");
But when the data become large,this method will be slow.
Short answer for fast need
1. Implement your Class to Serializable.
If you have any inner Classes don't forget to implement them to Serializable too!!
public class SportsData implements Serializable
public class Sport implements Serializable
List<Sport> clickedObj;
2. Put your object into Intent
Intent intent = new Intent(SportsAct.this, SportSubAct.class);
intent.putExtra("sport", clickedObj);
startActivity(intent);
3. And receive your object in the other Activity Class
Intent intent = getIntent();
Sport cust = (Sport) intent.getSerializableExtra("sport");
if your object class implements Serializable, you don't need to do anything else, you can pass a serializable object. that's what i use.
There are a couple of ways by which you can access variables or objects in other classes or Activity.
A. Database
B. shared preferences.
C. Object serialization.
D. A class that can hold common data can be named Common Utilities it depends on you.
E. Passing data through Intents and Parcelable Interface.
It depends upon your project needs.
A. Database
SQLite is an Open Source Database which is embedded into Android. SQLite supports standard relational database features like SQL syntax, transactions, and prepared statements.
Tutorials -- http://www.vogella.com/articles/AndroidSQLite/article.html
B. Shared Preferences
Suppose you want to store username. So there will be now two things a Key Username, Value Value.
How to store
// Create an object of SharedPreferences.
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
//now get Editor
SharedPreferences.Editor editor = sharedPref.edit();
//put your value
editor.putString("userName", "stackoverlow");
//commits your edits
editor.commit();
Using putString(),putBoolean(),putInt(),putFloat(),putLong() you can save your desired dtatype.
How to fetch
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
String userName = sharedPref.getString("userName", "Not Available");
http://developer.android.com/reference/android/content/SharedPreferences.html
C. Object Serialization
Object serialization is used if we want to save an object state to send it over the network or you can use it for your purpose also.
Use java beans and store in it as one of his fields and use getters and setter for that
JavaBeans are Java classes that have properties. Think of
properties as private instance variables. Since they're private, the only way
they can be accessed from outside of their class is through methods in the class. The
methods that change a property's value are called setter methods, and the methods
that retrieve a property's value are called getter methods.
public class VariableStorage implements Serializable {
private String inString ;
public String getInString() {
return inString;
}
public void setInString(String inString) {
this.inString = inString;
}
}
Set the variable in your mail method by using
VariableStorage variableStorage = new VariableStorage();
variableStorage.setInString(inString);
Then use object Serialzation to serialize this object and in your other class deserialize this object.
In serialization, an object can be represented as a sequence of bytes that includes the object's data as well as information about the object's type and the types of data stored in the object.
After a serialized object has been written into a file, it can be read from the file and deserialized that is, the type information and bytes that represent the object and its data can be used to recreate the object in memory.
If you want a tutorial for this to refer this link
http://javawithswaranga.blogspot.in/2011/08/serialization-in-java.html
Get variable in other classes
D. CommonUtilities
You can make a class by your self which can contain common data which you frequently need in your project.
Sample
public class CommonUtilities {
public static String className = "CommonUtilities";
}
E. Passing Data through Intents
Please refer to this tutorial for this option of passing data.
http://shri.blog.kraya.co.uk/2010/04/26/android-parcel-data-to-pass-between-activities-using-parcelable-classes/
You can use android BUNDLE to do this.
Create a Bundle from your class like:
public Bundle toBundle() {
Bundle b = new Bundle();
b.putString("SomeKey", "SomeValue");
return b;
}
Then pass this bundle with INTENT.
Now you can recreate your class object by passing bundle like
public CustomClass(Context _context, Bundle b) {
context = _context;
classMember = b.getString("SomeKey");
}
Declare this in your Custom class and use.
Thanks for parcelable help but i found one more optional solution
public class getsetclass implements Serializable {
private int dt = 10;
//pass any object, drwabale
public int getDt() {
return dt;
}
public void setDt(int dt) {
this.dt = dt;
}
}
In Activity One
getsetclass d = new getsetclass ();
d.setDt(50);
LinkedHashMap<String, Object> obj = new LinkedHashMap<String, Object>();
obj.put("hashmapkey", d);
Intent inew = new Intent(SgParceLableSampelActivity.this,
ActivityNext.class);
Bundle b = new Bundle();
b.putSerializable("bundleobj", obj);
inew.putExtras(b);
startActivity(inew);
Get Data In Activity 2
try { setContentView(R.layout.main);
Bundle bn = new Bundle();
bn = getIntent().getExtras();
HashMap<String, Object> getobj = new HashMap<String, Object>();
getobj = (HashMap<String, Object>) bn.getSerializable("bundleobj");
getsetclass d = (getsetclass) getobj.get("hashmapkey");
} catch (Exception e) {
Log.e("Err", e.getMessage());
}
I use Gson with its so powerful and simple api to send objects between activities,
Example
// This is the object to be sent, can be any object
public class AndroidPacket {
public String CustomerName;
//constructor
public AndroidPacket(String cName){
CustomerName = cName;
}
// other fields ....
// You can add those functions as LiveTemplate !
public String toJson() {
Gson gson = new Gson();
return gson.toJson(this);
}
public static AndroidPacket fromJson(String json) {
Gson gson = new Gson();
return gson.fromJson(json, AndroidPacket.class);
}
}
2 functions you add them to the objects that you want to send
Usage
Send Object From A to B
// Convert the object to string using Gson
AndroidPacket androidPacket = new AndroidPacket("Ahmad");
String objAsJson = androidPacket.toJson();
Intent intent = new Intent(A.this, B.class);
intent.putExtra("my_obj", objAsJson);
startActivity(intent);
Receive In B
#Override
protected void onCreate(Bundle savedInstanceState) {
Bundle bundle = getIntent().getExtras();
String objAsJson = bundle.getString("my_obj");
AndroidPacket androidPacket = AndroidPacket.fromJson(objAsJson);
// Here you can use your Object
Log.d("Gson", androidPacket.CustomerName);
}
I use it almost in every project i do and I have no performance issues.
I struggled with the same problem. I solved it by using a static class, storing any data I want in a HashMap. On top I use an extension of the standard Activity class where I have overriden the methods onCreate an onDestroy to do the data transport and data clearing hidden. Some ridiculous settings have to be changed e.g. orientation-handling.
Annotation:
Not providing general objects to be passed to another Activity is pain in the ass. It's like shooting oneself in the knee and hoping to win a 100 metres. "Parcable" is not a sufficient substitute. It makes me laugh... I don't want to implement this interface to my technology-free API, as less I want to introduce a new Layer... How could it be, that we are in mobile programming so far away from modern paradigm...
In your first Activity:
intent.putExtra("myTag", yourObject);
And in your second one:
myCustomObject myObject = (myCustomObject) getIntent().getSerializableExtra("myTag");
Don't forget to make your custom object Serializable:
public class myCustomObject implements Serializable {
...
}
Another way to do this is to use the Application object (android.app.Application). You define this in you AndroidManifest.xml file as:
<application
android:name=".MyApplication"
...
You can then call this from any activity and save the object to the Application class.
In the FirstActivity:
MyObject myObject = new MyObject();
MyApplication app = (MyApplication) getApplication();
app.setMyObject(myObject);
In the SecondActivity, do :
MyApplication app = (MyApplication) getApplication();
MyObject retrievedObject = app.getMyObject(myObject);
This is handy if you have objects that have application level scope i.e. they have to be used throughout the application. The Parcelable method is still better if you want explicit control over the object scope or if the scope is limited.
This avoid the use of Intents altogether, though. I don't know if they suits you. Another way I used this is to have int identifiers of objects send through intents and retrieve objects that I have in Maps in the Application object.
in your class model (Object) implement Serializable, for
Example:
public class MensajesProveedor implements Serializable {
private int idProveedor;
public MensajesProveedor() {
}
public int getIdProveedor() {
return idProveedor;
}
public void setIdProveedor(int idProveedor) {
this.idProveedor = idProveedor;
}
}
and your first Activity
MensajeProveedor mp = new MensajeProveedor();
Intent i = new Intent(getApplicationContext(), NewActivity.class);
i.putExtra("mensajes",mp);
startActivity(i);
and your second Activity (NewActivity)
MensajesProveedor mensajes = (MensajesProveedor)getIntent().getExtras().getSerializable("mensajes");
good luck!!
public class SharedBooking implements Parcelable{
public int account_id;
public Double betrag;
public Double betrag_effected;
public int taxType;
public int tax;
public String postingText;
public SharedBooking() {
account_id = 0;
betrag = 0.0;
betrag_effected = 0.0;
taxType = 0;
tax = 0;
postingText = "";
}
public SharedBooking(Parcel in) {
account_id = in.readInt();
betrag = in.readDouble();
betrag_effected = in.readDouble();
taxType = in.readInt();
tax = in.readInt();
postingText = in.readString();
}
public int getAccount_id() {
return account_id;
}
public void setAccount_id(int account_id) {
this.account_id = account_id;
}
public Double getBetrag() {
return betrag;
}
public void setBetrag(Double betrag) {
this.betrag = betrag;
}
public Double getBetrag_effected() {
return betrag_effected;
}
public void setBetrag_effected(Double betrag_effected) {
this.betrag_effected = betrag_effected;
}
public int getTaxType() {
return taxType;
}
public void setTaxType(int taxType) {
this.taxType = taxType;
}
public int getTax() {
return tax;
}
public void setTax(int tax) {
this.tax = tax;
}
public String getPostingText() {
return postingText;
}
public void setPostingText(String postingText) {
this.postingText = postingText;
}
public int describeContents() {
// TODO Auto-generated method stub
return 0;
}
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(account_id);
dest.writeDouble(betrag);
dest.writeDouble(betrag_effected);
dest.writeInt(taxType);
dest.writeInt(tax);
dest.writeString(postingText);
}
public static final Parcelable.Creator<SharedBooking> CREATOR = new Parcelable.Creator<SharedBooking>()
{
public SharedBooking createFromParcel(Parcel in)
{
return new SharedBooking(in);
}
public SharedBooking[] newArray(int size)
{
return new SharedBooking[size];
}
};
}
Passing the data:
Intent intent = new Intent(getApplicationContext(),YourActivity.class);
Bundle bundle = new Bundle();
i.putParcelableArrayListExtra("data", (ArrayList<? extends Parcelable>) dataList);
intent.putExtras(bundle);
startActivity(intent);
Retrieving the data:
Bundle bundle = getIntent().getExtras();
dataList2 = getIntent().getExtras().getParcelableArrayList("data");
the most easiest solution i found is..
to create a class with static data members with getters setters.
set from one activity and get from another activity that object.
activity A
mytestclass.staticfunctionSet("","",""..etc.);
activity b
mytestclass obj= mytestclass.staticfunctionGet();
Using google's Gson library you can pass object to another activities.Actually we will convert object in the form of json string and after passing to other activity we will again re-convert to object like this
Consider a bean class like this
public class Example {
private int id;
private String name;
public Example(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
We need to pass object of Example class
Example exampleObject=new Example(1,"hello");
String jsonString = new Gson().toJson(exampleObject);
Intent nextIntent=new Intent(this,NextActivity.class);
nextIntent.putExtra("example",jsonString );
startActivity(nextIntent);
For reading we need to do the reverse operation in NextActivity
Example defObject=new Example(-1,null);
//default value to return when example is not available
String defValue= new Gson().toJson(defObject);
String jsonString=getIntent().getExtras().getString("example",defValue);
//passed example object
Example exampleObject=new Gson().fromJson(jsonString,Example .class);
Add this dependancy in gradle
compile 'com.google.code.gson:gson:2.6.2'
you can use putExtra(Serializable..) and getSerializableExtra() methods to pass and retrieve objects of your class type; you will have to mark your class Serializable and make sure that all your member variables are serializable too...
Create Android Application
File >> New >> Android Application
Enter Project name: android-pass-object-to-activity
Pakcage: com.hmkcode.android
Keep other defualt selections, go Next till you reach Finish
Before start creating the App we need to create POJO class “Person” which we will use to send object from one activity to another. Notice that the class is implementing Serializable interface.
Person.java
package com.hmkcode.android;
import java.io.Serializable;
public class Person implements Serializable{
private static final long serialVersionUID = 1L;
private String name;
private int age;
// getters & setters....
#Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}
Two Layouts for Two Activities
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="#+id/tvName"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center_horizontal"
android:text="Name" />
<EditText
android:id="#+id/etName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10" >
<requestFocus />
</EditText>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="#+id/tvAge"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center_horizontal"
android:text="Age" />
<EditText
android:id="#+id/etAge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10" />
</LinearLayout>
<Button
android:id="#+id/btnPassObject"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="Pass Object to Another Activity" />
</LinearLayout>
activity_another.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<TextView
android:id="#+id/tvPerson"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:layout_gravity="center"
android:gravity="center_horizontal"
/>
</LinearLayout>
Two Activity Classes
1)ActivityMain.java
package com.hmkcode.android;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
public class MainActivity extends Activity implements OnClickListener {
Button btnPassObject;
EditText etName, etAge;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnPassObject = (Button) findViewById(R.id.btnPassObject);
etName = (EditText) findViewById(R.id.etName);
etAge = (EditText) findViewById(R.id.etAge);
btnPassObject.setOnClickListener(this);
}
#Override
public void onClick(View view) {
// 1. create an intent pass class name or intnet action name
Intent intent = new Intent("com.hmkcode.android.ANOTHER_ACTIVITY");
// 2. create person object
Person person = new Person();
person.setName(etName.getText().toString());
person.setAge(Integer.parseInt(etAge.getText().toString()));
// 3. put person in intent data
intent.putExtra("person", person);
// 4. start the activity
startActivity(intent);
}
}
2)AnotherActivity.java
package com.hmkcode.android;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;
public class AnotherActivity extends Activity {
TextView tvPerson;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_another);
// 1. get passed intent
Intent intent = getIntent();
// 2. get person object from intent
Person person = (Person) intent.getSerializableExtra("person");
// 3. get reference to person textView
tvPerson = (TextView) findViewById(R.id.tvPerson);
// 4. display name & age on textView
tvPerson.setText(person.toString());
}
}
I know this is late but it is very simple.All you have do is let your class implement Serializable like
public class MyClass implements Serializable{
}
then you can pass to an intent like
Intent intent=......
MyClass obje=new MyClass();
intent.putExtra("someStringHere",obje);
To get it you simpley call
MyClass objec=(MyClass)intent.getExtra("theString");
Easiest and java way of doing is : implement serializable in your pojo/model class
Recommended for Android for performance view: make model parcelable
Intent i = new Intent();
i.putExtra("name_of_extra", myParcelableObject);
startACtivity(i);
If you have a singleton class (fx Service) acting as gateway to your model layer anyway, it can be solved by having a variable in that class with getters and setters for it.
In Activity 1:
Intent intent = new Intent(getApplicationContext(), Activity2.class);
service.setSavedOrder(order);
startActivity(intent);
In Activity 2:
private Service service;
private Order order;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_quality);
service = Service.getInstance();
order = service.getSavedOrder();
service.setSavedOrder(null) //If you don't want to save it for the entire session of the app.
}
In Service:
private static Service instance;
private Service()
{
//Constructor content
}
public static Service getInstance()
{
if(instance == null)
{
instance = new Service();
}
return instance;
}
private Order savedOrder;
public Order getSavedOrder()
{
return savedOrder;
}
public void setSavedOrder(Order order)
{
this.savedOrder = order;
}
This solution does not require any serialization or other "packaging" of the object in question. But it will only be beneficial if you are using this kind of architecture anyway.
By far the easiest way IMHO to parcel objects. You just add an annotation tag above the object you wish to make parcelable.
An example from the library is below https://github.com/johncarl81/parceler
#Parcel
public class Example {
String name;
int age;
public Example(){ /*Required empty bean constructor*/ }
public Example(int age, String name) {
this.age = age;
this.name = name;
}
public String getName() { return name; }
public int getAge() { return age; }
}
First implement Parcelable in your class. Then pass object like this.
SendActivity.java
ObjectA obj = new ObjectA();
// Set values etc.
Intent i = new Intent(this, MyActivity.class);
i.putExtra("com.package.ObjectA", obj);
startActivity(i);
ReceiveActivity.java
Bundle b = getIntent().getExtras();
ObjectA obj = b.getParcelable("com.package.ObjectA");
The package string isn't necessary, just the string needs to be the same in both Activities
REFERENCE
Start another activity from this activity pass parameters via Bundle Object
Intent intent = new Intent(getBaseContext(), YourActivity.class);
intent.putExtra("USER_NAME", "xyz#gmail.com");
startActivity(intent);
Retrieve on another activity (YourActivity)
String s = getIntent().getStringExtra("USER_NAME");
This is ok for simple kind data type.
But if u want to pass complex data in between activity u need to serialize it first.
Here we have Employee Model
class Employee{
private String empId;
private int age;
print Double salary;
getters...
setters...
}
You can use Gson lib provided by google to serialize the complex data
like this
String strEmp = new Gson().toJson(emp);
Intent intent = new Intent(getBaseContext(), YourActivity.class);
intent.putExtra("EMP", strEmp);
startActivity(intent);
Bundle bundle = getIntent().getExtras();
String empStr = bundle.getString("EMP");
Gson gson = new Gson();
Type type = new TypeToken<Employee>() {
}.getType();
Employee selectedEmp = gson.fromJson(empStr, type);
In Koltin
Add kotlin extension in your build.gradle.
apply plugin: 'kotlin-android-extensions'
android {
androidExtensions {
experimental = true
}
}
Then create your data class like this.
#Parcelize
data class Sample(val id: Int, val name: String) : Parcelable
Pass Object with Intent
val sample = Sample(1,"naveen")
val intent = Intent(context, YourActivity::class.java)
intent.putExtra("id", sample)
startActivity(intent)
Get object with intent
val sample = intent.getParcelableExtra("id")
If you are not very particular about using the putExtra feature and just want to launch another activity with objects, you can check out the GNLauncher (https://github.com/noxiouswinter/gnlib_android/wiki#gnlauncher) library I wrote in an attempt to make this process more straight forward.
GNLauncher makes sending objects/data to an Activity from another Activity etc as easy as calling a function in the Activity with the required data as parameters. It introduces type safety and removes all the hassles of having to serialize, attaching to the intent using string keys and undoing the same at the other end.

How to pass a value to an activity from another WITHOUT starting it?

I want to pass a value from activity A to activity B without actually starting the activity B (therefore this rules out the use of Intents and putExtra). The activity B may or may not be started but when it does it needs to display the value passed to it by activity A.
I searched high and low but couldn't find any relevant solution to this seemingly simple question. Any help will be appreciated!
You can't find a solution, because it's something that goes against any logic.
Activity B can't do anything if not started and visible. Activity B might even already be destroyed by the system without you knowing.
You can use a lot of things to set some variables, which your Activity B can read such as in your Application, somewhere in your XML or simply any random class.
Still, you can not actually DO anything with any of these options, until you start Activity B and when you can, it will just effectively be the same as giving the extra data in the Intent.
Use global class like :
public class AppConfig {
Context context;
public AppConfig(Context mxt) {
context = mxt;
}
public static String filepath = null;
Then, in activity A before onCreate() :
AppConfig config;
Context context;
and in onCreate() method put this :
context = getApplicationContext();
config = new AppConfig(context);
And, in second Activity B before onCreate() :
AppConfig config;
Context context;
And, in onCreate() method put this :
context = getApplicationContext();
config = new AppConfig(context);
And set the value where you want. Hope this will help you.
You can use shared Preferences. Using this one Activity can set Value into it, and other activity can read from it.
So you need to keep a value for an activity . If it starts it means you have to use those values, otherwise you will discard those values. For this you can use a separate class with a variable of datatype that you want and you can create getter setter for that and you can use it.
Make use of the classes
public class GetSet {
public GetSet() {
super();
}
private static boolean passwordSet = false;
public static boolean isPasswordSet() {
return passwordSet;
}
public static void setPasswordSet(boolean passwordSet) {
GetSet.passwordSet = passwordSet;
}
}
You can access ths using GetSet.setPasswordSet(false);
and Boolean flag = GetSet.isPasswordSet();
Set the value as Global:
public class Global {
public static int mValue;
public static int getValue() {
return mValue;
}
public static void setValue(int mValue) {
Global.mValue = mValue;
}
}
I was looking for answers to that but I couldn't find it. So I found a way to do that.
First Activity
Intent intent = new Intent(this, SecondActivity.class);
intent.putExtra("Flag" , true);
startActivity(intent);
Second Activity
boolean flag;
flag = getIntent().getBooleanExtra("Flag" ,false);
if(flag == true)
{
this.finish();
}
So now you may send any data you want it will open the Second Activity and then immediately close it after you wouldn't even realize it. You may use Shared prefences to save your data for after usage.

How to reference the current or main activity from another class

I often find myself needing to access methods that require referencing some activity. For example, to use getWindowManager, I need to access some Activity. But often my code for using these methods is in some other class that has no reference to an activity. Up until now, I've either stored a reference to the main activity or passed the context of some activity to the class. Is there some better way to do this?
If you already have a valid context, just use this:
Activity activity = (Activity) context;
Passing context is better way for refrence Activity.
You can pass Context to another class.
IN Activity ::
AnotherClass Obj = new AnotherClass(this);
IN Another Class
class AnotherClass{
public AnotherClass(Context Context){
}
}
You can implement the necessary methods in your activity and implement a Handler. Then, simply pass a handler instance to your classes, where you can obtain a message for handler and send it to target.
You can make you application instance a singleton, and use it when you need a Context
An example is in this question:
Android Application as Singleton
This way, when you need a Context, you can get it with
Context context = MyApplication.getInstance()
This might not be the cleanest solution, but it has worked well for me so far
I found a way to get the Activity to a non-activity class that I have not seen discussed in forums. This was after numerous failed attempts at using getApplicationContext() and of passing the context in as a parameter to constructors, none of which gave Activity. I saw that my adapters were casting the incoming context to Activity so I made the same cast to my non-activity class constructors:
public class HandleDropdown extends Application{
...
public Activity activity;
...
public HandleDropdown() {
super();
}
public HandleDropdown(Activity context) {
this.activity = context;
this.context = context;
}
public void DropList(View v,Activity context) {
this.activity = context;
this.context = context;
...
}
After doing this cast conversion of Context to Activity I could use this.activity wherever I needed an Activity context.
I'm new to android so my suggestion may look guffy but what if you'll just create a reference to your activity as private property and assign that in OnCreate method? You can even create your CustomActivity with OnCreate like that and derive all your activities from your CustomActivity, not the generic Activity provided by android.
class blah extends Activity{
private Activity activityReference;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
activityReference = this;
}
}
after that you could use that the way you want, i.e. in
Intent i = new Intent(activityReference, SomeOtherActivity.class)
etc
There are many ways for Activities communication.
you can use:
the startActivityForResult method
a system of broadcast message and receiver (you can broadcast an event from the actual activity, and register a receiver in the target activity. Remember that the target activity must be previously initialized and non finished)
as you say, store a reference of the target activity wherever you need.
We built a framework for this. We have a BaseActivity class that inherits from Activity and it overrides all the lifecycle methods and has some static (class) variables that keep track of the activity stack. If anything wants to know what the current activity is, it just calls a static method in BaseActivity that returns the activity on top of our privately-managed stack.
It is kinda hacky, but it works. I'm not sure I would recommend it though.
Handle the Intent in the class you want to do these methods, and send your information to it in a Bundle like so:
Intent i = new Intent("android.intent.action.MAIN");
i.setComponent(new ComponentName("com.my.pkg","com.my.pkg.myActivity"));
Bundle data = new Bundle();
i.putExtras(data);
startActivityForResult(i);
Then use an OnActivityResultListener to grab the new data.
I solved this by making a singleton class has an instance of the class below as a member.
public class InterActivityReferrer <T> {
HashMap<Integer, T> map;
ArrayList<Integer> reserve;
public InterActivityReferrer() {
map = new HashMap<>();
reserve = new ArrayList<>();
}
public synchronized int attach(T obj) {
int id;
if (reserve.isEmpty()) {
id = reserve.size();
}
else {
id = reserve.remove(reserve.size() - 1);
}
map.put(id, obj);
return id;
}
public synchronized T get(int id) {
return map.get(id);
}
public synchronized T detach(int id) {
T obj = map.remove(id);
if (obj != null) reserve.add(id);
return obj;
}
}
This class can get a T object and return a unique integer assigned to the object by attach(). Assigned integers will not collide with each other unless HashMap fails. Each assigned integer will be freed when its corresponding object is detached by detach(). Freed integers will be reused when a new object is attached.
And from a singleton class:
public class SomeSingleton {
...
private InterActivityReferrer<Activity> referrer = new InterActivityReferrer<>();
...
public InterActivityReferrer<Activity> getReferrer() {return referrer;}
}
And from an activity that needs to be referred:
...
int activityID = SomeSingleton.getInstance().getReferrer().attach(this);
...
Now with this, a unique integer corresponding to this activity instance is returned. And an integer can be delivered into another starting activity by using Intent and putExtra().
...
Intent i = new Intent(this, AnotherActivity.class);
i.putExtra("thisActivityID", activityID);
startActivityForResult(i, SOME_INTEGER);
...
And from the another activity:
...
id refereeID = getIntent().getIntExtra("thisActivityID", -1);
Activity referredActivity = SomeSingleton.getInstance().getReferrer().get(refereeID);
...
And finally the activity can be referred. And InterActivityReferrer can be used for any other class.
I hope this helps.
public static Activity getLaunchActivity()
{
final Class<?> activityThreadClass = Class.forName("android.app.ActivityThread");
final Method methodApp = activityThreadClass.getMethod("currentApplication");
App = (Application) methodApp.invoke(null, (Object[]) null);
Intent launcherIntent = App.getPackageManager().getLaunchIntentForPackage(App.getPackageName());
launchActivityInfo = launcherIntent.resolveActivityInfo(App.getPackageManager(), 0);
Class<?> clazz;
try
{
clazz = Class.forName(launchActivityInfo.name);
if(clazz != null)
return Activity.class.cast(clazz.newInstance());
}
catch (Exception e)
{}
return null;
}
Just a guess since I haven't done this but it might work.
1) Get your applicationContext by making your Android Application class a Singleton.
2) Get your ActivityManager class from the context.
3) Get a list of RunningTaskInfos using getRunningTasks() on the ActivityManager.
4) Get the first RunningTaskInfo element from the list which should be the most recent task launched.
5) Call topActivity on that RunningTaskInfo which should return you the top activity on the activity stack for that task.
Now, this seems like a LOT more work than any of the other methods mentioned here, but you can probably encapsulate this in a static class and just call it whenever. It seems like it might be the only way to get the top activity on the stack without adding references to the activities.

How do I write an android JUnit test when my activity relies on extras passed through an Intent?

I am writing an android Junit test for a class that relies on extras passed to it through an Intent. I was able to get the class working properly, but I would still like to know how to write a unit test for such a class, as the test still fails.
public class AddClassEvent extends Activity{
private String eventType;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle extras = getIntent().getExtras();
final String cNo = extras.getString("CourseNum");
// create a model instance
final StudentDBModel model = new StudentDBModel(this);
setContentView(R.layout.add_class_event);
.....
.....
}
}
The test class looks like...
public class AddClassEventTest extends ActivityInstrumentationTestCase2<AddClassEvent>{
private StudentDBModel model = null;
private RenamingDelegatingContext context = null;
public AddClassEventTest() {
super("com.UI", AddClassEvent.class);
}
/**
* This method is called before each test.
*/
#Override
public void setUp() {
context = new RenamingDelegatingContext(getActivity(), "test_");
model = new StudentDBModel(context);
}
/*
* This function will test addNewClassEvent() from StudentDBModel
*/
public void testAddNewClassEvent(){
ContentValues courseValues = new ContentValues();
courseValues.put("CourseId", "60-415");
courseValues.put("CourseName", "Advanced Database Design");
courseValues.put("Section", "1");
courseValues.put("Location", "Erie");
courseValues.put("Credit", "3");
courseValues.put("ProfEmail", "rfortier#uwindsor.ca");
courseValues.put("Website", "cs.uwindsor.ca");
model.addNewCourses(courseValues);
int numEventsBefore = model.getNumClassEvents();
ContentValues values = new ContentValues();
values.put("EventName", "Assignment 1");
values.put("CourseId", "60-415");
values.put("EventType", "Assignment");
values.put("EventWeight", "8");
values.put("DueDate", "10/20/2010");
model.addNewClassEvent(values);
int numEventsAfter = model.getNumClassEvents();
assertEquals(numEventsBefore + 1, numEventsAfter);
}
}
The problem is, the extra that I am passing to the class AddClassEvent is a PK for my DB that is created in another class and passed to AddClassEvent through an Intent. Whenever I run the test I get a NULL Pointer Exception on the on the line:
final String cNo = extras.getString("CourseNum");
How do I create the info from the extra in the Junit Test? Is there a way to get this test to work? I have searched extensively and can't find an answer. Is there some way to falsely create the extras in the Junit test so that it thinks it is being created by the other class? If so, could someone please show me how?
OK so I have tried to take your advice and I have changed my setUp function to:
#Override
public void setUp() {
context = new RenamingDelegatingContext(getActivity(), "test_");
model = new StudentDBModel(context);
Intent addEvent = new Intent();
addEvent.setClassName("com.UI", "com.UI.AddClassEvent");
addEvent.putExtra("CourseNum", "60-415");
setActivityIntent(addEvent);
getActivity();
}
but I am still getting a NULL Pointer exception. Is my syntax wrong? Any suggestions?
The class you inherit, ActivityInstrumentationTestCase2, allows you to mock Intents. From the documentation:
You can inject custom Intents into your Activity (see setActivityIntent(Intent)).
The documentation for setActivityIntent() further clarifies:
Call this method before the first call
to getActivity() to inject a
customized Intent into the Activity
under test.
If you do not call this, the default
intent will be provided. If you call
this after your Activity has been
started, it will have no effect.
So you should be able to place a call to this method inside your setUp() before your call to getActivity(). You can pass in a mocked Intent into setActivityIntent like you mentioned -- just build a fake Intent with extras that you'd expect the Activity to see.
OK, I figured out my mistake! The code for setUp was just in the wrong order. It should look like:
#Override
public void setUp() {
Intent addEvent = new Intent();
addEvent.setClassName("com.UI", "com.UI.AddClassEvent");
addEvent.putExtra("CourseNum", "60-415");
setActivityIntent(addEvent);
context = new RenamingDelegatingContext(getActivity(), "test_");
model = new StudentDBModel(context);
}
I was calling getActivity() twice and the first call was ahead of the Intent. By using the correct order, the test runs fine. Thanks for the help McStretch.

How to send an object from one Android Activity to another using Intents?

How can I pass an object of a custom type from one Activity to another using the putExtra() method of the class Intent?
If you're just passing objects around then Parcelable was designed for this. It requires a little more effort to use than using Java's native serialization, but it's way faster (and I mean way, WAY faster).
From the docs, a simple example for how to implement is:
// simple class that just has one member property as an example
public class MyParcelable implements Parcelable {
private int mData;
/* everything below here is for implementing Parcelable */
// 99.9% of the time you can just ignore this
#Override
public int describeContents() {
return 0;
}
// write your object's data to the passed-in Parcel
#Override
public void writeToParcel(Parcel out, int flags) {
out.writeInt(mData);
}
// this is used to regenerate your object. All Parcelables must have a CREATOR that implements these two methods
public static final Parcelable.Creator<MyParcelable> CREATOR = new Parcelable.Creator<MyParcelable>() {
public MyParcelable createFromParcel(Parcel in) {
return new MyParcelable(in);
}
public MyParcelable[] newArray(int size) {
return new MyParcelable[size];
}
};
// example constructor that takes a Parcel and gives you an object populated with it's values
private MyParcelable(Parcel in) {
mData = in.readInt();
}
}
Observe that in the case you have more than one field to retrieve from a given Parcel, you must do this in the same order you put them in (that is, in a FIFO approach).
Once you have your objects implement Parcelable it's just a matter of putting them into your Intents with putExtra():
Intent i = new Intent();
i.putExtra("name_of_extra", myParcelableObject);
Then you can pull them back out with getParcelableExtra():
Intent i = getIntent();
MyParcelable myParcelableObject = (MyParcelable) i.getParcelableExtra("name_of_extra");
If your Object Class implements Parcelable and Serializable then make sure you do cast to one of the following:
i.putExtra("parcelable_extra", (Parcelable) myParcelableObject);
i.putExtra("serializable_extra", (Serializable) myParcelableObject);
You'll need to serialize your object into some kind of string representation. One possible string representation is JSON, and one of the easiest ways to serialize to/from JSON in android, if you ask me, is through Google GSON.
In that case you just put the string return value from (new Gson()).toJson(myObject); and retrieve the string value and use fromJson to turn it back into your object.
If your object isn't very complex, however, it might not be worth the overhead, and you could consider passing the separate values of the object instead.
You can send serializable object through intent
// send where details is object
ClassName details = new ClassName();
Intent i = new Intent(context, EditActivity.class);
i.putExtra("Editing", details);
startActivity(i);
//receive
ClassName model = (ClassName) getIntent().getSerializableExtra("Editing");
And
Class ClassName implements Serializable {
}
For situations where you know you will be passing data within an application, use "globals" (like static Classes)
Here is what Dianne Hackborn (hackbod - a Google Android Software Engineer) had to say on the matter:
For situations where you know the activities are running in the same
process, you can just share data through globals. For example, you
could have a global HashMap<String, WeakReference<MyInterpreterState>>
and when you make a new MyInterpreterState come up with a unique name
for it and put it in the hash map; to send that state to another
activity, simply put the unique name into the hash map and when the
second activity is started it can retrieve the MyInterpreterState from
the hash map with the name it receives.
Your class should implements Serializable or Parcelable.
public class MY_CLASS implements Serializable
Once done you can send an object on putExtra
intent.putExtra("KEY", MY_CLASS_instance);
startActivity(intent);
To get extras you only have to do
Intent intent = getIntent();
MY_CLASS class = (MY_CLASS) intent.getExtras().getSerializable("KEY");
If your class implements Parcelable use next
MY_CLASS class = (MY_CLASS) intent.getExtras().getParcelable("KEY");
I hope it helps :D
implement serializable in your class
public class Place implements Serializable{
private int id;
private String name;
public void setId(int id) {
this.id = id;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Then you can pass this object in intent
Intent intent = new Intent(this, SecondAct.class);
intent.putExtra("PLACE", Place);
startActivity(intent);
int the second activity you can get data like this
Place place= (Place) getIntent().getSerializableExtra("PLACE");
But when the data become large,this method will be slow.
Short answer for fast need
1. Implement your Class to Serializable.
If you have any inner Classes don't forget to implement them to Serializable too!!
public class SportsData implements Serializable
public class Sport implements Serializable
List<Sport> clickedObj;
2. Put your object into Intent
Intent intent = new Intent(SportsAct.this, SportSubAct.class);
intent.putExtra("sport", clickedObj);
startActivity(intent);
3. And receive your object in the other Activity Class
Intent intent = getIntent();
Sport cust = (Sport) intent.getSerializableExtra("sport");
if your object class implements Serializable, you don't need to do anything else, you can pass a serializable object. that's what i use.
There are a couple of ways by which you can access variables or objects in other classes or Activity.
A. Database
B. shared preferences.
C. Object serialization.
D. A class that can hold common data can be named Common Utilities it depends on you.
E. Passing data through Intents and Parcelable Interface.
It depends upon your project needs.
A. Database
SQLite is an Open Source Database which is embedded into Android. SQLite supports standard relational database features like SQL syntax, transactions, and prepared statements.
Tutorials -- http://www.vogella.com/articles/AndroidSQLite/article.html
B. Shared Preferences
Suppose you want to store username. So there will be now two things a Key Username, Value Value.
How to store
// Create an object of SharedPreferences.
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
//now get Editor
SharedPreferences.Editor editor = sharedPref.edit();
//put your value
editor.putString("userName", "stackoverlow");
//commits your edits
editor.commit();
Using putString(),putBoolean(),putInt(),putFloat(),putLong() you can save your desired dtatype.
How to fetch
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
String userName = sharedPref.getString("userName", "Not Available");
http://developer.android.com/reference/android/content/SharedPreferences.html
C. Object Serialization
Object serialization is used if we want to save an object state to send it over the network or you can use it for your purpose also.
Use java beans and store in it as one of his fields and use getters and setter for that
JavaBeans are Java classes that have properties. Think of
properties as private instance variables. Since they're private, the only way
they can be accessed from outside of their class is through methods in the class. The
methods that change a property's value are called setter methods, and the methods
that retrieve a property's value are called getter methods.
public class VariableStorage implements Serializable {
private String inString ;
public String getInString() {
return inString;
}
public void setInString(String inString) {
this.inString = inString;
}
}
Set the variable in your mail method by using
VariableStorage variableStorage = new VariableStorage();
variableStorage.setInString(inString);
Then use object Serialzation to serialize this object and in your other class deserialize this object.
In serialization, an object can be represented as a sequence of bytes that includes the object's data as well as information about the object's type and the types of data stored in the object.
After a serialized object has been written into a file, it can be read from the file and deserialized that is, the type information and bytes that represent the object and its data can be used to recreate the object in memory.
If you want a tutorial for this to refer this link
http://javawithswaranga.blogspot.in/2011/08/serialization-in-java.html
Get variable in other classes
D. CommonUtilities
You can make a class by your self which can contain common data which you frequently need in your project.
Sample
public class CommonUtilities {
public static String className = "CommonUtilities";
}
E. Passing Data through Intents
Please refer to this tutorial for this option of passing data.
http://shri.blog.kraya.co.uk/2010/04/26/android-parcel-data-to-pass-between-activities-using-parcelable-classes/
You can use android BUNDLE to do this.
Create a Bundle from your class like:
public Bundle toBundle() {
Bundle b = new Bundle();
b.putString("SomeKey", "SomeValue");
return b;
}
Then pass this bundle with INTENT.
Now you can recreate your class object by passing bundle like
public CustomClass(Context _context, Bundle b) {
context = _context;
classMember = b.getString("SomeKey");
}
Declare this in your Custom class and use.
Thanks for parcelable help but i found one more optional solution
public class getsetclass implements Serializable {
private int dt = 10;
//pass any object, drwabale
public int getDt() {
return dt;
}
public void setDt(int dt) {
this.dt = dt;
}
}
In Activity One
getsetclass d = new getsetclass ();
d.setDt(50);
LinkedHashMap<String, Object> obj = new LinkedHashMap<String, Object>();
obj.put("hashmapkey", d);
Intent inew = new Intent(SgParceLableSampelActivity.this,
ActivityNext.class);
Bundle b = new Bundle();
b.putSerializable("bundleobj", obj);
inew.putExtras(b);
startActivity(inew);
Get Data In Activity 2
try { setContentView(R.layout.main);
Bundle bn = new Bundle();
bn = getIntent().getExtras();
HashMap<String, Object> getobj = new HashMap<String, Object>();
getobj = (HashMap<String, Object>) bn.getSerializable("bundleobj");
getsetclass d = (getsetclass) getobj.get("hashmapkey");
} catch (Exception e) {
Log.e("Err", e.getMessage());
}
I use Gson with its so powerful and simple api to send objects between activities,
Example
// This is the object to be sent, can be any object
public class AndroidPacket {
public String CustomerName;
//constructor
public AndroidPacket(String cName){
CustomerName = cName;
}
// other fields ....
// You can add those functions as LiveTemplate !
public String toJson() {
Gson gson = new Gson();
return gson.toJson(this);
}
public static AndroidPacket fromJson(String json) {
Gson gson = new Gson();
return gson.fromJson(json, AndroidPacket.class);
}
}
2 functions you add them to the objects that you want to send
Usage
Send Object From A to B
// Convert the object to string using Gson
AndroidPacket androidPacket = new AndroidPacket("Ahmad");
String objAsJson = androidPacket.toJson();
Intent intent = new Intent(A.this, B.class);
intent.putExtra("my_obj", objAsJson);
startActivity(intent);
Receive In B
#Override
protected void onCreate(Bundle savedInstanceState) {
Bundle bundle = getIntent().getExtras();
String objAsJson = bundle.getString("my_obj");
AndroidPacket androidPacket = AndroidPacket.fromJson(objAsJson);
// Here you can use your Object
Log.d("Gson", androidPacket.CustomerName);
}
I use it almost in every project i do and I have no performance issues.
I struggled with the same problem. I solved it by using a static class, storing any data I want in a HashMap. On top I use an extension of the standard Activity class where I have overriden the methods onCreate an onDestroy to do the data transport and data clearing hidden. Some ridiculous settings have to be changed e.g. orientation-handling.
Annotation:
Not providing general objects to be passed to another Activity is pain in the ass. It's like shooting oneself in the knee and hoping to win a 100 metres. "Parcable" is not a sufficient substitute. It makes me laugh... I don't want to implement this interface to my technology-free API, as less I want to introduce a new Layer... How could it be, that we are in mobile programming so far away from modern paradigm...
In your first Activity:
intent.putExtra("myTag", yourObject);
And in your second one:
myCustomObject myObject = (myCustomObject) getIntent().getSerializableExtra("myTag");
Don't forget to make your custom object Serializable:
public class myCustomObject implements Serializable {
...
}
Another way to do this is to use the Application object (android.app.Application). You define this in you AndroidManifest.xml file as:
<application
android:name=".MyApplication"
...
You can then call this from any activity and save the object to the Application class.
In the FirstActivity:
MyObject myObject = new MyObject();
MyApplication app = (MyApplication) getApplication();
app.setMyObject(myObject);
In the SecondActivity, do :
MyApplication app = (MyApplication) getApplication();
MyObject retrievedObject = app.getMyObject(myObject);
This is handy if you have objects that have application level scope i.e. they have to be used throughout the application. The Parcelable method is still better if you want explicit control over the object scope or if the scope is limited.
This avoid the use of Intents altogether, though. I don't know if they suits you. Another way I used this is to have int identifiers of objects send through intents and retrieve objects that I have in Maps in the Application object.
in your class model (Object) implement Serializable, for
Example:
public class MensajesProveedor implements Serializable {
private int idProveedor;
public MensajesProveedor() {
}
public int getIdProveedor() {
return idProveedor;
}
public void setIdProveedor(int idProveedor) {
this.idProveedor = idProveedor;
}
}
and your first Activity
MensajeProveedor mp = new MensajeProveedor();
Intent i = new Intent(getApplicationContext(), NewActivity.class);
i.putExtra("mensajes",mp);
startActivity(i);
and your second Activity (NewActivity)
MensajesProveedor mensajes = (MensajesProveedor)getIntent().getExtras().getSerializable("mensajes");
good luck!!
public class SharedBooking implements Parcelable{
public int account_id;
public Double betrag;
public Double betrag_effected;
public int taxType;
public int tax;
public String postingText;
public SharedBooking() {
account_id = 0;
betrag = 0.0;
betrag_effected = 0.0;
taxType = 0;
tax = 0;
postingText = "";
}
public SharedBooking(Parcel in) {
account_id = in.readInt();
betrag = in.readDouble();
betrag_effected = in.readDouble();
taxType = in.readInt();
tax = in.readInt();
postingText = in.readString();
}
public int getAccount_id() {
return account_id;
}
public void setAccount_id(int account_id) {
this.account_id = account_id;
}
public Double getBetrag() {
return betrag;
}
public void setBetrag(Double betrag) {
this.betrag = betrag;
}
public Double getBetrag_effected() {
return betrag_effected;
}
public void setBetrag_effected(Double betrag_effected) {
this.betrag_effected = betrag_effected;
}
public int getTaxType() {
return taxType;
}
public void setTaxType(int taxType) {
this.taxType = taxType;
}
public int getTax() {
return tax;
}
public void setTax(int tax) {
this.tax = tax;
}
public String getPostingText() {
return postingText;
}
public void setPostingText(String postingText) {
this.postingText = postingText;
}
public int describeContents() {
// TODO Auto-generated method stub
return 0;
}
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(account_id);
dest.writeDouble(betrag);
dest.writeDouble(betrag_effected);
dest.writeInt(taxType);
dest.writeInt(tax);
dest.writeString(postingText);
}
public static final Parcelable.Creator<SharedBooking> CREATOR = new Parcelable.Creator<SharedBooking>()
{
public SharedBooking createFromParcel(Parcel in)
{
return new SharedBooking(in);
}
public SharedBooking[] newArray(int size)
{
return new SharedBooking[size];
}
};
}
Passing the data:
Intent intent = new Intent(getApplicationContext(),YourActivity.class);
Bundle bundle = new Bundle();
i.putParcelableArrayListExtra("data", (ArrayList<? extends Parcelable>) dataList);
intent.putExtras(bundle);
startActivity(intent);
Retrieving the data:
Bundle bundle = getIntent().getExtras();
dataList2 = getIntent().getExtras().getParcelableArrayList("data");
the most easiest solution i found is..
to create a class with static data members with getters setters.
set from one activity and get from another activity that object.
activity A
mytestclass.staticfunctionSet("","",""..etc.);
activity b
mytestclass obj= mytestclass.staticfunctionGet();
Using google's Gson library you can pass object to another activities.Actually we will convert object in the form of json string and after passing to other activity we will again re-convert to object like this
Consider a bean class like this
public class Example {
private int id;
private String name;
public Example(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
We need to pass object of Example class
Example exampleObject=new Example(1,"hello");
String jsonString = new Gson().toJson(exampleObject);
Intent nextIntent=new Intent(this,NextActivity.class);
nextIntent.putExtra("example",jsonString );
startActivity(nextIntent);
For reading we need to do the reverse operation in NextActivity
Example defObject=new Example(-1,null);
//default value to return when example is not available
String defValue= new Gson().toJson(defObject);
String jsonString=getIntent().getExtras().getString("example",defValue);
//passed example object
Example exampleObject=new Gson().fromJson(jsonString,Example .class);
Add this dependancy in gradle
compile 'com.google.code.gson:gson:2.6.2'
you can use putExtra(Serializable..) and getSerializableExtra() methods to pass and retrieve objects of your class type; you will have to mark your class Serializable and make sure that all your member variables are serializable too...
Create Android Application
File >> New >> Android Application
Enter Project name: android-pass-object-to-activity
Pakcage: com.hmkcode.android
Keep other defualt selections, go Next till you reach Finish
Before start creating the App we need to create POJO class “Person” which we will use to send object from one activity to another. Notice that the class is implementing Serializable interface.
Person.java
package com.hmkcode.android;
import java.io.Serializable;
public class Person implements Serializable{
private static final long serialVersionUID = 1L;
private String name;
private int age;
// getters & setters....
#Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}
Two Layouts for Two Activities
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="#+id/tvName"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center_horizontal"
android:text="Name" />
<EditText
android:id="#+id/etName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10" >
<requestFocus />
</EditText>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="#+id/tvAge"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center_horizontal"
android:text="Age" />
<EditText
android:id="#+id/etAge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10" />
</LinearLayout>
<Button
android:id="#+id/btnPassObject"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="Pass Object to Another Activity" />
</LinearLayout>
activity_another.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<TextView
android:id="#+id/tvPerson"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:layout_gravity="center"
android:gravity="center_horizontal"
/>
</LinearLayout>
Two Activity Classes
1)ActivityMain.java
package com.hmkcode.android;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
public class MainActivity extends Activity implements OnClickListener {
Button btnPassObject;
EditText etName, etAge;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnPassObject = (Button) findViewById(R.id.btnPassObject);
etName = (EditText) findViewById(R.id.etName);
etAge = (EditText) findViewById(R.id.etAge);
btnPassObject.setOnClickListener(this);
}
#Override
public void onClick(View view) {
// 1. create an intent pass class name or intnet action name
Intent intent = new Intent("com.hmkcode.android.ANOTHER_ACTIVITY");
// 2. create person object
Person person = new Person();
person.setName(etName.getText().toString());
person.setAge(Integer.parseInt(etAge.getText().toString()));
// 3. put person in intent data
intent.putExtra("person", person);
// 4. start the activity
startActivity(intent);
}
}
2)AnotherActivity.java
package com.hmkcode.android;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;
public class AnotherActivity extends Activity {
TextView tvPerson;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_another);
// 1. get passed intent
Intent intent = getIntent();
// 2. get person object from intent
Person person = (Person) intent.getSerializableExtra("person");
// 3. get reference to person textView
tvPerson = (TextView) findViewById(R.id.tvPerson);
// 4. display name & age on textView
tvPerson.setText(person.toString());
}
}
I know this is late but it is very simple.All you have do is let your class implement Serializable like
public class MyClass implements Serializable{
}
then you can pass to an intent like
Intent intent=......
MyClass obje=new MyClass();
intent.putExtra("someStringHere",obje);
To get it you simpley call
MyClass objec=(MyClass)intent.getExtra("theString");
Easiest and java way of doing is : implement serializable in your pojo/model class
Recommended for Android for performance view: make model parcelable
Intent i = new Intent();
i.putExtra("name_of_extra", myParcelableObject);
startACtivity(i);
If you have a singleton class (fx Service) acting as gateway to your model layer anyway, it can be solved by having a variable in that class with getters and setters for it.
In Activity 1:
Intent intent = new Intent(getApplicationContext(), Activity2.class);
service.setSavedOrder(order);
startActivity(intent);
In Activity 2:
private Service service;
private Order order;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_quality);
service = Service.getInstance();
order = service.getSavedOrder();
service.setSavedOrder(null) //If you don't want to save it for the entire session of the app.
}
In Service:
private static Service instance;
private Service()
{
//Constructor content
}
public static Service getInstance()
{
if(instance == null)
{
instance = new Service();
}
return instance;
}
private Order savedOrder;
public Order getSavedOrder()
{
return savedOrder;
}
public void setSavedOrder(Order order)
{
this.savedOrder = order;
}
This solution does not require any serialization or other "packaging" of the object in question. But it will only be beneficial if you are using this kind of architecture anyway.
By far the easiest way IMHO to parcel objects. You just add an annotation tag above the object you wish to make parcelable.
An example from the library is below https://github.com/johncarl81/parceler
#Parcel
public class Example {
String name;
int age;
public Example(){ /*Required empty bean constructor*/ }
public Example(int age, String name) {
this.age = age;
this.name = name;
}
public String getName() { return name; }
public int getAge() { return age; }
}
First implement Parcelable in your class. Then pass object like this.
SendActivity.java
ObjectA obj = new ObjectA();
// Set values etc.
Intent i = new Intent(this, MyActivity.class);
i.putExtra("com.package.ObjectA", obj);
startActivity(i);
ReceiveActivity.java
Bundle b = getIntent().getExtras();
ObjectA obj = b.getParcelable("com.package.ObjectA");
The package string isn't necessary, just the string needs to be the same in both Activities
REFERENCE
Start another activity from this activity pass parameters via Bundle Object
Intent intent = new Intent(getBaseContext(), YourActivity.class);
intent.putExtra("USER_NAME", "xyz#gmail.com");
startActivity(intent);
Retrieve on another activity (YourActivity)
String s = getIntent().getStringExtra("USER_NAME");
This is ok for simple kind data type.
But if u want to pass complex data in between activity u need to serialize it first.
Here we have Employee Model
class Employee{
private String empId;
private int age;
print Double salary;
getters...
setters...
}
You can use Gson lib provided by google to serialize the complex data
like this
String strEmp = new Gson().toJson(emp);
Intent intent = new Intent(getBaseContext(), YourActivity.class);
intent.putExtra("EMP", strEmp);
startActivity(intent);
Bundle bundle = getIntent().getExtras();
String empStr = bundle.getString("EMP");
Gson gson = new Gson();
Type type = new TypeToken<Employee>() {
}.getType();
Employee selectedEmp = gson.fromJson(empStr, type);
In Koltin
Add kotlin extension in your build.gradle.
apply plugin: 'kotlin-android-extensions'
android {
androidExtensions {
experimental = true
}
}
Then create your data class like this.
#Parcelize
data class Sample(val id: Int, val name: String) : Parcelable
Pass Object with Intent
val sample = Sample(1,"naveen")
val intent = Intent(context, YourActivity::class.java)
intent.putExtra("id", sample)
startActivity(intent)
Get object with intent
val sample = intent.getParcelableExtra("id")
If you are not very particular about using the putExtra feature and just want to launch another activity with objects, you can check out the GNLauncher (https://github.com/noxiouswinter/gnlib_android/wiki#gnlauncher) library I wrote in an attempt to make this process more straight forward.
GNLauncher makes sending objects/data to an Activity from another Activity etc as easy as calling a function in the Activity with the required data as parameters. It introduces type safety and removes all the hassles of having to serialize, attaching to the intent using string keys and undoing the same at the other end.

Categories

Resources