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)
Related
I'm devlopping an Android app made of multiple Activities and I have to pass ab Object between them, but I can't pass it by using intents because the class of the object doesn't implement serializable, how can I do it?
I CAN'T MODIFY THE SOURCE CODE OF MY CLASS
Thanks :)
public class MyClass { //stuff }
//I can't modify this source code
MyClass m = new MyClass(); //object I have to pass
Suppose there is a data object class named StudentDataObject having some data types.
StudentDataObject studentDataObject = new StudentDataObject();
Gson gson = new Gson();
String studentDataObjectAsAString = gson.toJson(studentDataObject);
Now we are passing it from one activity to another activity using intent.
Intent intent = new Intent(FromActivity.this, ToActivity.class);
intent.putExtra("MyStudentObjectAsString", studentDataObjectAsAString);
startActivity(intent);
Now we are in new activity, we get that object here using following line.
Gson gson = new Gson();
String studentDataObjectAsAString = getIntent().getStringExtra("MyStudentObjectAsString");
StudentDataObject studentDataObject = gson.fromJson(studentDataObjectAsAString, StudentDataObject.class);
Activity itself know where from I am called, so we can directly write getIntent() method.
Here we only need to add one dependency of GSON we can add it using following line in build.gradle file.
compile 'com.google.code.gson:gson:2.6.2'
And one thing is that implement StudentDataObject as a Parcelable and if showing error then just press alt+Enter and implement methods.
Try this once, Hope it will work.
Sample Example for StudentDataObject should be like :-
public class StudentDataObject implements Parcelable {
// fields
//empty constructor
//parameterised constructor
//getters and setters
//toString method
//last implement some Parcelable methods
}
First of all create Parcelable data model.
public class DataModel implements Parcelable {
private int mData;
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel out, int flags) {
out.writeInt(mData);
}
public static final Parcelable.Creator<DataModel> CREATOR
= new Parcelable.Creator<DataModel>() {
public DataModel createFromParcel(Parcel in) {
return new DataModel(in);
}
public DataModel[] newArray(int size) {
return new DataModel[size];
}
};
private DataModel(Parcel in) {
mData = in.readInt();
}
}
put object into intent
intent.putExtra("KEY", object);
get object from intent
object = getIntent().getExtras().getParcelable("KEY");
This code may help you:
public class EN implements Serializable {
//... you don't need implement any methods when you implements Serializable
}
FirstActivity
EN enumb = new EN();
Intent intent = new Intent(getActivity(), NewActivity.class);
intent.putExtra("en", enumb); //second param is Serializable
startActivity(intent);
SecandActivity
Bundle extras = getIntent().getExtras();
if (extras != null) {
en = (EN)getIntent().getSerializableExtra("en"); //Obtaining data
}
Passing data through intent using Serializable
Here is my object class Book.java
import android.os.Parcel;
import android.os.Parcelable;
public class Book implements Parcelable {
// book basics
private String title;
private String author;
// main constructor
public Book(String title, String author) {
this.title = title;
this.author = author;
}
// getters
public String getTitle() { return title; }
public String getAuthor() { return author; }
// write object values to parcel for storage
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(title);
dest.writeString(author);
}
public Book(Parcel parcel) {
title = parcel.readString();
author = parcel.readString();
}
public static final Parcelable.Creator<Book> CREATOR = new Parcelable.Creator<Book>() {
#Override
public Book createFromParcel(Parcel parcel) {
return new Book(parcel);
}
#Override
public Book[] newArray(int size) {
return new Book[0];
}
};
public int describeContents() {
return hashCode();
}
}
Now you can pass object like this
Button button = (Button) findViewById(R.id.submit_button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Book book = new Book(mBkTitle.getText().toString(),
mBkAuthor.getText().toString());
Intent intent = new Intent(MainActivity.this, BookActivity.class);
intent.putExtra("Book", book);
startActivity(intent);
}
});
Now object will be received like this in receiving ReceivingActivity.java
Intent intent = getIntent();
Book book = intent.getParcelableExtra("Book");
mBkTitle.setText("Title:" + book.getTitle());
mBkAuthor.setText("Author:" + book.getAuthor());
You need to implement parcelable and then pass it via intent. Dont use Serializable cause is way slower than parcelable.
Read here how to make your object parcelable: https://developer.android.com/reference/android/os/Parcelable.html
after you dont it, pass your object like this:
intent.putExtra("KEY", your_object);
to read it:
getIntent().getExtras().getParcelable("KEY");
Extend the class and implement serializable or parcelable in the inherited class and use its objects as in other answers.
Class NewClass extends MyClass implements serializable {
//Create a constructor matching super
}
Use objects of this class instead of my class
You can pass a custom object from one activity to another through intent in 2 ways.
By implements Serializable
By implements Parcelable
(1) By implements Serializable no need to do anything just implement Serializable
into your class like
public class Note implements Serializable {
private int id;
private String title;
}
(2) By implementing Parcelable (you have to follow the Parcel write and read with same order)
public class Note implements Parcelable {
private int id;
private String title;
public Note() {
}
Note(Parcel in){
this.id = in.readInt();
this.title = in.readString();
}
public void setId(int id) {
this.id = id;
}
public int getId() {
return id;
}
public void setTitle(String title) {
this.title = title;
}
public String getTitle() {
return title;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(id);
dest.writeString(title);
}
public static final Parcelable.Creator<Note> CREATOR = new Parcelable.Creator<Note>(){
#Override
public Note createFromParcel(Parcel source) {
return new Note(source);
}
#Override
public Note[] newArray(int size) {
return new Note[size];
}
};
}
and then in your activity
Activity A
intent.putExtra("NOTE", note);
Activity B
Note note = (Note) getIntent().getExtras().get("NOTE");
Imp: Parcelable is 10 times faster than Serializable
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
Im fighting with this some time and still don't know how to make it work. So i have class Player with constructor
Player(String playerName, double playerCash)
{
this.playerName = playerName;
this.playerCash = playerCash;
}
In MainActivity i make a player object
Player player = new Player("player", 100);
And now in TextView in SecondActivity i would like to use
playerCash = (TextView) findViewById(R.id.playerCash);
playerCash.setText(player.getPlayerCash());
Can someone explain me how i can make it works? I get cannot resolve symbol player. Thanks in advance
You can implement Parcelable interface for Player class and then pass instance of it from the MainActivity through Intent to the SecondActivity.
I am unsure if what you have posted is your entire class, or if you obviated a part of it. I will write this answer, assuming that is your entire class.
So, here is the deal: you need to create methods in your class for you to get and set data to/from it.
public class Player() implements Parcelable {
private String playerName;
private String playerCash;
public Player(String playerName, String playerCash) {
this.playerName = playerName;
this.playerCash = playerCash;
}
public String getPlayerName() {
return playerName;
}
public void setPlayerName(String playerName) {
this.playerName = playerName;
}
public String getPlayerCash() {
return playerCash;
}
public void setPlayerCash(String playerCash) {
this.playerCash = playerCash;
}
public Player(Parcel in) {
String[] data = new String[2];
in.readStringArray(data);
this.playerData = data[0];
this.playerCash = data[1];
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeStringArray(new String[] {this.playerName,
this.playerCash});
}
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
public Player createFromParcel(Parcel in) {
return new Player(in);
}
public Player[] newArray(int size) {
return new Player[size];
}
};
}
edit
I didn't read the part where you say you want to share it between Activities. I only noticed it because someone mentioned implementing Parcelable, which does help your problem.
Anyway, I edited my code to implement it.
To share data between Activities you will also need an intent, and there you can share the data stored on your Player class:
Intent i = new Intent();
i.putExtra("player", new Player("Jhon", "Over 9000!");
And in your 2nd Activity, to get it you would do:
Bundle b = getIntent().getExtras();
Player player = b.getParcelable("player");
Hope that helps.
I have a class that I'm using for parsing data from a csv file (called CSVReader), inside of that there is some methods for the parsing as well as a couple of strings and a list that is of a custom object type (List allRecords).
What I'm doing is when the app loads, parsing all the data into that list and then trying to pass that information along to the next activity but inside the next activity I keep getting allRecords as being null.
LoginActivity
CSVReader data = new CSVReader();
data.populateRecords(this);
Intent intent = new Intent(LoginActivity.this, Find.class);
Bundle bundle = new Bundle();
bundle.putParcelable("list", data);
intent.putExtra("bundle", bundle);
startActivity(intent);
I've gone through the debugger and the bundle definitely has the data in there.
Find
Intent intent = getIntent();
Bundle bundle = intent.getBundleExtra("bundle");
data = (CSVReader) bundle.getParcelable("list");
Using the debugger still, and mMap (in the bundle) is now null and so is data.
Am I doing something wrong? Both classes DummyData and CSVReader implement Parcelable.
EDIT: Adding custom class CSVReader:
List<DummyData> allRecords;
private String base;
private String location;
private String partner;
public static Creator<CSVReader> CREATOR = new Creator<CSVReader>(){
#Override
public CSVReader createFromParcel(Parcel source){
return new CSVReader(source);
}
#Override
public CSVReader[] newArray(int size) {
return new CSVReader[size];
}
};
private CSVReader(Parcel in){
allRecords = new ArrayList<DummyData>();
in.readTypedList(allRecords, DummyData.CREATOR);
base = in.readString();
location = in.readString();
partner = in.readString();
}
...
...
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(base);
dest.writeString(location);
dest.writeString(partner);
dest.writeList(allRecords);
}
[EDIT]
I was looking over your code again, and noticed you're writing the List to the parcel LAST and reading the list from the parcel FIRST. You have to read items from the parcel in the order they are written. Try putting dest.writeList(allRecords) at the top of the method so it is the first item written, or you can put in.readList(allRecords, DummyData.class.getClassLoader()) at the bottom of the list in that method.
Give it a shot.
//////////////////////////////////////////////
From the docs,
public final void readTypedList (List<T> list, Creator<T> c)
Read into the given List items containing a particular object type
that were written with writeTypedList(List) at the current
dataPosition(). The list must have previously been written via
writeTypedList(List) with the same object type.
You're using writeList() to write the data to the parcel. Try using writeTypedList(). You could also try changing readTypedList() with readList() I believe. Something like:
in.readList(allRecords, CSVReader.class.getClassLoader());
Hope this helps.
If you plan to pass data to another activity, you need to use objects of classes that implement Parcelable. Here is an example,
package com.weather.model;
import java.util.ArrayList;
import java.util.List;
import android.os.Parcel;
import android.os.Parcelable;
public class Forcast implements Parcelable {
private String id;
private String code;
private String message;
private City city;
private String count;
private List<Weather> weatherList = new ArrayList<Weather>();
public Forcast(){
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public City getCity() {
return city;
}
public void setCity(City city) {
this.city = city;
}
public String getCount() {
return count;
}
public void setCount(String count) {
this.count = count;
}
public List<Weather> getWeatherList() {
return weatherList;
}
public void setWeatherList(List<Weather> weather) {
this.weatherList = weather;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(id);
dest.writeString(code);
dest.writeString(message);
dest.writeParcelable(city, flags);
dest.writeString(count);
dest.writeList(weatherList);
}
public static final Parcelable.Creator<Forcast> CREATOR = new Parcelable.Creator<Forcast>() {
#Override
public Forcast createFromParcel(Parcel source) {
return new Forcast(source);
}
#Override
public Forcast[] newArray(int size) {
return new Forcast[size];
}
};
protected Forcast(Parcel in){
id = in.readString();
code = in.readString();
message = in.readString();
city = (City)in.readParcelable(City.class.getClassLoader());
count = in.readString();
in.readList(weatherList, Weather.class.getClassLoader());
}
}
I included City model so you can see how it goes for an object in comparison to list of objects. Assume you have a Forcast instance with all the values as 'forcast' ( Forcast forcast = new Forcast() or something similar)
Intent intent = new Intent(this, SomeActivity.class);
intent.putExtra(com.weather.model,forcast)
startActivity(intent)
I hope that helps
You need to put bundle object by using putExtras method. Then you can get the bundle by using getIntent().getExtras().
Intent intent = new Intent(LoginActivity.this, Find.class);
Bundle bundle = new Bundle();
bundle.putParcelable("list", data);
intent.putExtras( bundle);
startActivity(intent);
Intent intent = getIntent();
Bundle bundle = intent.getExtras();
data = (CSVReader) bundle.getParcelable("list");
I'm trying my first Parcelable transfer and it doesn't go fine. This is my Parcelable class :
public class Element implements Parcelable, Serializable {
private static final long serialVersionUID = 1L;
String name;
String id;
byte[] password;
public static final Parcelable.Creator<Element> CREATOR = new Parcelable.Creator<Element>() {
public Element createFromParcel(Parcel source) {
return new Element(source);
}
public Element[] newArray(int size) {
return new Element[size];
}
};
private Element(Parcel in){
name = in.readString();
id = in.readString();
password = new byte[in.readInt()];
in.readByteArray(password);
}
public Element(String name,String id,byte[] password){
this.name=name;
this.id=id;
this.password=password;
}
#Override
public String toString() {
return name;
}
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeString(id);
dest.writeInt(password.length);
dest.writeByteArray(password);
}
}
As you see, it's a simple Parcelable with 2 String fields and 1 byteArray.
Now I send it to the second activity via my main one :
//Inside the main activity
Intent i = new Intent(MainActivity.this, DisplayActivity.class);
i.putExtra("element", (Parcelable)adapter.getItem(pos));
startActivity(i);
And then, I receive the Parcelable in the second activity :
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.display);
Element e = getIntent().getExtras().getParcelable("element");
//this line makes my app crash. No idea why.
Try it this way:
Element obj = new Element();
//set your data here before send
Intent i = new Intent(this, MyActivity.class);
i.putExtra("com.package.Element", obj);
startActivity(i);
Then to retrieve it:
public class MyActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle b = getIntent().getExtras();
Element obj = b.getParcelable("com.package.Element");
}
}
I was also struggling with the same issue. In your manifest in the MyActivity activity add:
android:launchMode="singleTop"
It solved the issue for me.
<activity android:name="com.example.myapp.MyActivity"
android:label="#string/title_myactivity"
android:launchMode="singleTop">
</activity>
Why would you implement both Parcelable and Serializable?