Android: how to pass object between activities with object contains other objects - android

I'm begginer in Android and i try to pass object between activities with object contains other objects but errors appear.
A solution?
I try to pass object with serializable :
lALL.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View v,
int position, long arg3) {
System.out.println(position);
Locataire l = new Locataire(getResources());
l.setNom("test");
l.setPrenom("test");
Intent intent = new Intent(MainActivity.this, Etat_lieux.class);
intent.putExtra("EDL", l);
startActivity(intent);
}
});
And
public class Locataire implements Serializable{
private String ref;
private String civilite;
private String nom;
private String prenom;
private Contact contact = new Contact();
private Adresse adresse = new Adresse();
private String DG;
private boolean IsGarantPresent;
private boolean IsColocation;
private Resources res;
public Locataire(Resources res)
{
this.res = res;
}
Contact,Adresse
public class Contact implements Serializable{
protected String tel;
protected String mobile;
protected String fax;
protected String email;
protected String www;
And ressource is Context getResources() of first activity

If you want to pass data between activities in your own app you should use startActivity, startActivityForResult and onActivityResult. You create a Bundle object and encapsulate your data in it with putExtra. Then you retrieve this object in your onCreate method.
http://developer.android.com/training/basics/intents/result.html
Otherwise, if you want to pass data between activities in your app and activities in another app you should use explicit or implicit intents.
http://developer.android.com/training/basics/intents/sending.html

If you want to pass object in extras... you have to make the object implements serializable..and make all it sub-objects implement serializalbe..
then use bundle.putSerializable(OBJECT)..

Related

Pass values from to 2 different activities to the one that is not startActivity

The activity that i want to pass values is main activity-menu of app. From this activity i do startActivity the all activity with buttons. I want to retrieve values from two different activities at the same time as I mentioned to the title and when I startActivity each actity i want to send values.Any help?
Use Static fields or methods
Have Static String fields (or methods to compute and then return strings) in all classes that you want to get values from, then have your activity-menu get them and pass them into the your startActivity intent.
Example:
class activity-menu extends Activity{
public void StartActivityC(){
// Get value from Activity_A
string value_A = Activity_A.myString;
// Get value from Activity_B
string value_B = Activity_B.myString;
// Store both values in an Intent:
Intent intent = new Intent(this, Activity_C.class);
// store the string from Activity A under "value_A"
intent.putExtra("value_A", value_A);
// store the string from Activity B under "value_B"
intent.putExtra("value_B", value_B);
startActivity(intent);
}
}
public class Activity_A extends Activity{
public static String myString;
public Activity_A(){
myString = "this is from activity A";
}
}
public class Activity_B extends Activity{
public static String myString;
public Activity_B(){
myString = "this is from activity B";
}
}
public class Activity_C extends Activity{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Get the Intent that started this activity and extract the strings:
Intent intent = getIntent();
String value_A = intent.getStringExtra("value_A");
string value_B = intent.getStringExtra("value_B");
// DONE!
}
}

Which way is better for pass a large list of data from one activity to another activity - android?

I need to pass a large list of data from one activity to another activity,which way is better?
First way(for example):
ArrayList<myModel> myList = new ArrayList<myModel>();
intent.putExtra("mylist", myList);
Second way(for example) :
ActivityTwo act = new ActivityTwo();
act.getDataMethod(listValues);
Intent i = new Intent(this, ActivityTwo.class);
startActivity(i);
And in another activity(ActivityTwo) I get data from getDataMethod.
If the data you want to send is really big (around 1MB). The best way to pass it is to store it in persistent storage in ActivityA and access it in ActivityB.
The approach with passing it via Parcerable/Serializable is risky as you may end up with TransactionTooLargeException when trying to pass around 1MB of data.
The approach with passing it via Singleton class is even worse as when you are in ActivityB and application is recreated (it was long in background/memory was low) you will loose data from singleton (process is recreated) and nobody will set it, ActivityB will be launched and it wont have data from AcitvityA (as it was never created).
In general you shouldn't pass data through intents, you should pass arguments/identifiers which then you can use to fetch data from db/network/etc.
Best way to pass large data list from one Activity to another in Android is Parcelable . You first create Parcelable pojo class and then create Array-List and pass into bundle like key and value pair and then pass bundle into intent extras.
Below I put one sample User Pojo class that implements Parcelable interface.
import android.os.Parcel;
import android.os.Parcelable;
/**
* Created by CHETAN JOSHI on 2/1/2017.
*/
public class User implements Parcelable {
private String city;
private String name;
private int age;
public User(String city, String name, int age) {
super();
this.city = city;
this.name = name;
this.age = age;
}
public User(){
super();
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
#SuppressWarnings("unused")
public User(Parcel in) {
this();
readFromParcel(in);
}
private void readFromParcel(Parcel in) {
this.city = in.readString();
this.name = in.readString();
this.age = in.readInt();
}
public int describeContents() {
return 0;
}
public final Parcelable.Creator<User> CREATOR = new Parcelable.Creator<User>() {
public User createFromParcel(Parcel in) {
return new User(in);
}
public User[] newArray(int size) {
return new User[size];
}
};
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(city);
dest.writeString(name);
dest.writeInt(age);
}
}
ArrayList<User> info = new ArrayList<User>();
info .add(new User("kolkata","Jhon",25));
info .add(new User("newyork","smith",26));
info .add(new User("london","kavin",25));
info .add(new User("toranto","meriyan",30));
Intent intent = new Intent(MyActivity.this,NextActivity.class);
Bundle bundle = new Bundle();
bundle.putParcelableArrayList("user_list",info );
intent.putExtras(bundle);`
startActivity(intent );
To me serialized objects/list is better way.
`Intent intent = ....
Bundle bundle = new Bundle();
ArrayList<String> myList = new ArrayList<String>();
bundle.putSerializable("mylist", myList);
intent.putExtras(bundle);`
Use the first approach. However you will need to use the following method call to put it into the Intent:
ArrayList<String> myList = new ArrayList<String>();
intent.putStringArrayListExtra("mylist",myList);
The to get the list out of the intent in the receiving Activity:
ArrayList<String> myList = getIntent().getStringArrayListExtra("mylist");
If you have a huge list of data it is better way to save the data in Singleton java class and use set/get to save & get the data in application level.
Sharing large data as intent bundle may chances to lose data.
Application.class
add this in you manifest file
<application
android:name=".App"
-----
</application>
public class App extends Application {
public ArrayList<Object> newsList;
#Override
public void onCreate() {
super.onCreate();
}
public void setHugeData(ArrayList<Object> list){
this.newsList = list;
}
public ArrayList<Object> getHugeData(){
return newsList;
}
}
in ActivityA.class
ArrayList<Object> info = new ArrayList<>();
// save data
((App)getApplication()).setHugeData(info);
in ActvityB.class
ArrayList<Object> info = new ArrayList<>();
// get the data
info = ((App)getApplication()).getHugeData();
You can use such libraries as Eventbus to pass models through activities or you can put your model in ContentValues (https://developer.android.com/reference/android/content/ContentValues.html) class - it is parcable and you can pass it through intent. A good practice is to implement two methods in your Model class - toContentValues() and fromContentValues().
Something like this:
public class DealShort extends BaseResponse implements ContentValuesProvider {
#SerializedName("id")
#Expose
private long id = -1;
#SerializedName("full_price")
#Expose
private double fullPrice;
public static DealShort fromContentValues(ContentValues cv) {
DealShort deal = new DealShort();
deal.id = cv.getAsLong(DbContract.Product.SERVER_ID);
deal.fullPrice = cv.getAsLong(DbContract.CategoriesProducts.CATEGORY_ID);
}
public ContentValues toContentValues() {
ContentValues cv = new ContentValues();
cv.put(DbContract.Product.SERVER_ID, id);
cv.put(DbContract.Product.FULL_PRICE, fullPrice);
return cv;
}
}
1,You can use Singleton class,like below code:
public class MusicListHolder {
private ArrayList<MusicInfo> musicInfoList;
public ArrayList<MusicInfo> getMusicInfoList() {
return musicInfoList;
}
public void setMusicInfoList(ArrayList<MusicInfo> musicInfoList) {
this.musicInfoList = musicInfoList;
}
private static final MusicListHolder holder = new MusicListHolder();
public static MusicListHolder getInstance() {
return holder;
}
}
it's easy and useful!
2,You can use Application,just put your data in Application before you use it!
3,You can use Eventbus
4,You can put your data in a file/sqlite/...,maybe it's slow and conflict,but it's workable

Passing and ArrayList<Service> through intent

I have a class called Service, which is used to create Service objects using this constructor
public Service(int id, String service_name, String service_code) {
this.id = id;
this.service_name = service_name;
this.service_code = service_code;
}
then I create a list call service list as with the following signature
List<Service> serviceList = new ArrayList<Service>
I have try to pass this ArrayList through Intent Object like this
Intent i = new Intent(Classname.this, anotherClass.class);
i.putExtras("serviceList",serviceList);
startActivity(i);
But it fails. What is the way I pass through intent with ArrayList object.
Your custom class has to implement Parcelable or Serializable in order to serialize/de-serialize within an Intent.
Your class Service has to look like this for example (used a generator http://www.parcelabler.com/)
public class Service implements Parcelable {
private int id;
private String service_name;
private String service_code;
public Service(int id, String service_name, String service_code) {
this.id = id;
this.service_name = service_name;
this.service_code = service_code;
}
protected Service(Parcel in) {
id = in.readInt();
service_name = in.readString();
service_code = in.readString();
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(id);
dest.writeString(service_name);
dest.writeString(service_code);
}
#SuppressWarnings("unused")
public static final Parcelable.Creator<Service> CREATOR = new Parcelable.Creator<Service>() {
#Override
public Service createFromParcel(Parcel in) {
return new Service(in);
}
#Override
public Service[] newArray(int size) {
return new Service[size];
}
};
}
Then you can use getIntent().getParcelableArrayListExtra() with casting
ArrayList<Service> serviceList= intent.<Service>getParcelableArrayList("list"));
For sending you use it like this
intent.putParcelableArrayListExtra("list", yourServiceArrayList);
Note that the yourServiceArrayList should be an ArrayList
if it is List the you can pass through
intent.putParcelableArrayListExtra("list", (ArrayList<? extends Parcelable>) yourServiceArrayList);
You can use parcelable interface for 'Service' class, and send object through
intent using 'putParcelableArrayListExtra' method and to retrive data you can use
'getParcelableArrayListExtra'.
For your reference
refer this link
Implement object class with Serializable .
eg.
class abc implements Serializable{
//your code
}
then try this code
ArrayList<abc> fileList = new ArrayList<abc>();
Intent intent = new Intent(MainActivity.this, secondActivity.class);
intent.putSerializable("arraylisty",filelist);
startActivity(intent);
and on other side receive intent like
your arraylist objact=intent.getSerializableExtra(String name)

Android passing ArrayList via Bundle [duplicate]

I am trying to pass my own custom object into a bundle:
Bundle b = new Bundle();
STMessage message = (STMessage)a.getAdapter().getItem(position);
b.putObject("message",message);
I get the error:
The method putObject(String, Object) is undefined for the type Bundle
One way is to have your custom object implement the Parcelable interface and use Bundle.putParcelable/Bundle.getParcelable
Model Class
package com.sam.bundleobjectpass;
import java.io.Serializable;
/**
* Created by Samir on 31.8.2016.
*/
public class Model implements Serializable {
private String name;
private String surName;
private int age;
public Model(String name, String surName, int age) {
this.name = name;
this.surName = surName;
this.age = age;
}
public String getName() {
return name;
}
public String getSurName() {
return surName;
}
public int getAge() {
return age;
}
}
MainActivity
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Model model = new Model("Sam", "Sami",32);
Intent i = new Intent(MainActivity.this, ReceiverActivity.class);
i.putExtra("Editing", model); // sending our object. In Kotlin is the same
startActivity(i);
}
}
ReceiverActivity
public class ReceiverActivity extends Activity {
TextView txt_name;
TextView txt_surname;
TextView txt_age;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.second);
txt_name = (TextView)findViewById(R.id.txt_name);
txt_surname = (TextView)findViewById(R.id.txt_surname);
txt_age = (TextView)findViewById(R.id.txt_age);
// receiving our object
Model model = (Model) getIntent().getSerializableExtra("Editing");
txt_name.setText(model.getName());
txt_surname.setText(model.getSurName());
txt_age.setText(""+model.getAge());
}
}
// Kotlin
val model: ProgramModel? = intent.getSerializableExtra("Editing") as ProgramModel?
model?.let { // means if not null or empty
txt_act_daily_topic.text = it.title
}
Since using Parsable is designed for high performance IPC transport as mentioned in some of the comments, I tried using a different approach.
My approach uses GSON library by google.
Example
public class Person{
private String name;
private int age;
// Getter and Setters omitted
}
You can have a method in utility class that returns Gson instance, this is for the sake of clean code and organisation. I will use GsonBuilder incase someone what to register custom adapter.
public class Utils {
private static Gson gson;
public static Gson getGsonParser() {
if(null == gson) {
GsonBuilder builder = new GsonBuilder();
gson = builder.create();
}
return gson;
}
}
Moment of truth!
PUT
Bundle args = new Bundle();
String personJsonString = Utils.getGsonParser().toJson(person);
args.putString(PERSON_KEY, personJsonString);
GET
Bundle args = getArguments();
String personJsonString = args.getString(PERSON_KEY);
Person person= Utils.getGsonParser().fromJson(personJsonString, Person.class);
Currently I don't know the performance limitation of this approach. But it works just fine
Make your custom object Parcelable or Serializable then use putParcelable or putSerializable.
Depending on the complexity of your object one or other may be easier.
As Ryan stated. Also if you only want to pass one object on a soft kill consider using onRetainConfigurationInstance and getLastNonConfigurationInstance to pass the serializable object. The entire object tree must be serializable. If you are passing the object via an intent, consider refactoring the object code to a Parceable code later, once the architecture has stabilized. Finally, consider using the fully qualified name of the class when storing the object into the Bundle as in:
inPWState= (PasswordState) getIntent().getSerializableExtra("jalcomputing.confusetext.PasswordState");
Hope that helps.
JAL
It's work
if you make your object class as Serializable
class your_data_class implements Serializable

Transferring object data from one activity to another activity

I am having a class EmployeeInfo as the following:
public class EmployeeInfo {
private int id; // Employee ID
private String name; // Employee Name
private int age;// Employee Age
public int getEmployeeID() {
return id;
}
public void setEmployeeID(int id) {
this.id = id;
}
public String getEmployeeName() {
return name;
}
public void setEmployeeName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age= age;
}
}
ArrayList<EmployeeInfo> employeeInfo object contains the emplyoyee info data for multiple employees.
I want to transfer the data( ArrayList employeeInfo ) from Activity1 to Activity2.
Is using Parcelable the only way to transfer the data from Activity1 to Activity2?
If not , what are the alternatives.
If yes ,kindly provide the prototype code of Parcelable along with the sample code on how to transfer the object data from Activity1 to Activity2.
Here is my implementation of Parceleble:
public class ProfileData implements Parcelable {
private int gender;
private String name;
private String birthDate;
public ProfileData(Parcel source) {
gender = source.readInt();
name = source.readString();
birthDate = source.readString();
}
public ProfileData(int dataGender, String dataName, String dataBDate) {
gender = dataGender;
name = dataName;
birthDate = dataBDate;
}
// Getters and Setters are here
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel out, int flags) {
out.writeInt(gender);
out.writeString(name);
out.writeString(birthDate);
}
public static final Parcelable.Creator<ProfileData> CREATOR
= new Parcelable.Creator<ProfileData>() {
public ProfileData createFromParcel(Parcel in) {
return new ProfileData(in);
}
public ProfileData[] newArray(int size) {
return new ProfileData[size];
}
};
}
and how I transfer data:
Intent parcelIntent = new Intent().setClass(ActivityA.this, ActivityB.class);
ProfileData data = new ProfileData(profile.gender, profile.getFullName(), profile.birthDate);
parcelIntent.putExtra("profile_details", data);
startActivity(parcelIntent);
and take data:
Bundle data = getIntent().getExtras();
ProfileData profile = data.getParcelable("profile_details");
You can simply let your EmployeeInfo class implement Serializable. Or you can send data like this
intent.putExtra("id", employInfo.getEmployeeID());
intent.putExtra("name", employInfo.getEmployeeName());
intent.putExtra("age", employInfo.getAge());
If you need to transfer a list of your custom classes, i'd use the first approach. So you would be able to put entire list as Serializable.
However they said that everyone should use Parcelable instead because it's "way faster". Tbh, I'd never used it, because it needs more effort and I doubt somebody can realize the difference in speed in a regular application w/o a load of data sending via intent
Good question. Looking at the docs and doing armchair coding:
It may be possible to pass an object between Activities by calling putExtras(Bundle) and myBundle.putSerializable. The object and the entire object tree would need to implement serializable.
JAL
EDIT: The answer is yes:
It is possible to pass an immutable object between Activities by calling putExtras(Bundle) and myBundle.putSerializable. The object and the entire object tree would need to implement serializable. This is a basic tenet of Object Oriented Programming, passing of stateful messages.
First we create the immutable object by declaring a new class:
package jalcomputing.confusetext;
import java.io.Serializable;
/*
* Immutable messaging object to pass state from Activity Main to Activity ManageKeys
* No error checking
*/
public final class MainManageKeysMessage implements Serializable {
private static final long serialVersionUID = 1L;
public final int lengthPassword;
public final long timeExpire;
public final boolean isValidKey;
public final int timeoutType;
public MainManageKeysMessage(int lengthPassword, long timeExpire, boolean isValidKey, int timeoutType){
this.lengthPassword= lengthPassword;
this.timeExpire= timeExpire;
this.isValidKey= isValidKey;
this.timeoutType= timeoutType;
}
}
Then we create an immutable stateful instance of the class, a message, in the parent activity, and send it in an intent as in:
private void LaunchManageKeys() {
Intent i= new Intent(this, ManageKeys.class); // no param constructor
// push data (4)
MainManageKeysMessage message= new MainManageKeysMessage(lengthPassword,timeExpire,isValidKey,timeoutType);
Bundle b= new Bundle();
b.putSerializable("jalcomputing.confusetext.MainManageKeysMessage", message);
i.putExtras(b);
startActivityForResult(i,REQUEST_MANAGE_KEYS); // used for callback
}
Finally, we retrieve the object in the child activity.
try {
inMessage= (MainManageKeysMessage) getIntent().getSerializableExtra("jalcomputing.confusetext.MainManageKeysMessage");
lengthPassword= inMessage.lengthPassword;
timeoutType= inMessage.timeoutType;
isValidKey= inMessage.isValidKey;
timeExpire= inMessage.timeExpire;
} catch(Exception e){
lengthPassword= -1;
timeoutType= TIMEOUT_NEVER;
isValidKey= true;
timeExpire= LONG_YEAR_MILLIS;
}
Well there is another way to transfer an object.We can use application to transfer object and this is way is far better way in my opinion.
First of all create your custom application in your main package.
public class TestApplication extends Application {
private Object transferObj;
#Override
public void onCreate() {
super.onCreate();
// ACRA.init(this);
}
public Object getTransferObj() {
return transferObj;
}
public void setTransferObj(Object transferObj) {
this.transferObj = transferObj;
}
}
Now use setTransfer and get transfer methods to move abjects from one activity to other like:
To Transfer:
((TestApplication) activity.getApplication()).setTransferObj(Yous object);
ToRecieve:
Object obj=((TestApplication) activity.getApplication()).getTransferObj();
NOTE
Always remember to make entry of this application in manifest application tag:
<application
android:name=".TestApplication">
</application>
You can convert your object to jsonstring using Gson or Jakson and pass using intent as string and read the json in another activity.

Categories

Resources