This question already has answers here:
Parcelable and inheritance in Android
(3 answers)
Closed 7 years ago.
I have this ConstantData class which holds my JSON indexes, I need to pass them between activities with extras. But before that, I have to implement Parcelable to the objects of this class first.
My question is, how should I declare the object within my class here and put every object inside a variable?
I'm a newbie and I'm totally clueless right now. Thank you. Feel free to modify my code below.
ConstantData.java
public class ConstantData{
public static String project_title = "project title";
public static String organization_title = "organization title";
public static String keyword = "keyword";
public static String short_code = "short code";
public static String project_description = "description";
public static String smallImageUrl = "smallImageUrl";
public static String bigImageUrl = "bigImageUrl";
public static String price= "price";
public static String country= "country";
public static ArrayList<Project> projectsList = new ArrayList<Project>();
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel out, int flags) {
out.writeString(project_title);
out.writeString(organization_title);
out.writeString(keyword);
out.writeString(short_code);
out.writeString(project_description);
out.writeString(smallImageUrl);
out.writeString(bigImageUrl);
out.writeString(price);
out.writeString(country);
}
public static final Parcelable.Creator<ConstantData> CREATOR
= new Parcelable.Creator<ConstantData>() {
public ConstantData createFromParcel(Parcel in) {
return new ConstantData(in);
}
public ConstantData[] newArray(int size) {
return new ConstantData[size];
}
};
private ConstantData(Parcel in) {
project_title = in.readString();
organization_title = in.readString();
keyword = in.readString();
short_code = in.readString();
project_description = in.readString();
smallImageUrl = in.readString();
bigImageUrl = in.readString();
price = in.readString();
country = in.readString();
}
}
In case my question is not clear enough, you can look up this question: How to send an object from one Android Activity to another using Intents?
There he wrote myParcelableObject, I just don't know how to make the parcelable object.
EDIT
Project.java
public class Project {
public String project_title;
public String organization_title;
public String keyword;
public String short_code;
public String project_description;
public String smallImageUrl;
public String bigImageUrl;
public String price;
public String country;
}
You need to implement the Parcelable interface
public class ConstantData implements Parcelable {
public void writeToParcel(Parcel out, int flags) {
out.writeString(project_title);
....
out.writeString(country);
out.writeList(projectsList); // <<--
}
private ConstantData(Parcel in) {
project_title = in.readString();
....
country = in.readString();
projectsList = in.readList();
I think for the writing of the projectsList to work, the Project class also needs to implement Parcelable.
See e.g. this class for an example.
Related
I am rewriting c code to Java to run on an Android-based BeagleBone Black. Since there are not struc types in java, I'm defining the data structures using public static class methods. However, in the structures are an array of sub-structures. As a model, say we want to define a class called Satellites. In each Satellite are Transponders and for each transponder is the channel information. I am trying to figure out how to declare and then initialize the sub-classes inside the class. My basic definition is:
public static final int SATELLITE_MAX = 50;
public static final int TRANSPONDER_MAX = 24;
public static final int CHANNEL_MAX = 36;
public static class satellite_struct {
public string satId;
public string satName;
public string satLocation;
public class transponder_struct {
public int frequency;
public char polarity;
public class channels_struct {
public string channel_name;
public string encryption;
public int sid;
}
}
}
I can instantiate the satellite structure class as follows:
satellite_struct satellites[] = new satellite_struct[SATELLITE_MAX]
but, how do I initialize the x transponders and y channels inside this class?
Thanks.
The "easiest" solution would be:
public static class satellite_struct {
public string satId;
public string satName;
public string satLocation;
public class transponder_struct {
public int frequency;
public char polarity;
public class channels_struct {
public string channel_name;
public string encryption;
public int sid;
}
public channels_struct[] channels = new channel_struct[ CHANNEL_MAX ];
}
public transponder_struct transponders = new transponder_struct[ TRANSPONDER_MAX ];
}
Given that you defined
satellite_struct satellites[] = new satellite_struct[SATELLITE_MAX];
You can then access them by (e.g.):
satellites[x].transponders[y].channels[z].channel_name
However, you'd probably want to Java-fy it a bit:
public static class Satellite {
public string satId;
public string satName;
public string satLocation;
public class Transponder {
public int frequency;
public char polarity;
public class Channel {
public string channel_name;
public string encryption;
public int sid;
}
public Channel[] channels = new Channel[ CHANNEL_MAX ];
}
public Transponder transponders = new Transponder[ TRANSPONDER_MAX ];
}
Class names are customarily upper-case in Java. If this is a direct translation to an existing structure, the above should do, but you might want to use a List or SparseArray instead of arrays.
Declare transponders here;
Declare channels here;
public static class satellite_struct {
public string satId;
public string satName;
public string satLocation;
public []transponder t;
public []channel c;
public satellite_struct(int x,int y)
{
//here
t=new transponder[x];
for(....)
t[i]=new transponder(params);
c=new channel[y];
for(....)
c[i]=new channel(params);
}
}
I got it to work as follows, and Java-ifying my syntax. The issue was with where to place the [] declaring an array of objects:
public static class Satellite {
public String satId;
public String satName;
public String satLocation;
public static class Transponder {
public int frequency;
public char polarity;
public static class Channel {
public String channel_name;
public String encryption;
public int sid;
}
public Channel channels[] = new Channel[CHANNELS_MAX];
}
public Transponder transponders[] = new Transponder[TRANSPONDERS_MAX];
}
Then, in my main code:
Structures.Satellite satellites[] = new Structures.Satellite[SATELLITES_MAX];
satellites[0].transponders[0].channels[0].channel_name="HELLO";
Update: It appears that while the IDE allows me to 'see' the transponders and channels when coding, when the code runs it returns error "all elements are null" for these sub-array values. How to initialize these?
I just changed all serializable classes in my project to parcelable classes.
Everything is working fine, except for that one class which is made of an ArrayList containing another ArrayList. I already debugged.
There is no error when writing this ArrayList. But I get an error while reading it.
This is the class where the error happens:
public class Timetable implements Parcelable
{
private int actLap = 0;
private ArrayList<Lap> timetable;
private ArrayList<Location> loggedLocations;
private Date startTime; ...
...
public void writeToParcel(Parcel out, int flags)
{
out.writeInt(actLap);
out.writeTypedList(timetable); //no error here
out.writeTypedList(loggedLocations); ...
...
private Timetable(Parcel in)
{
actLap = in.readInt();
in.readTypedList(timetable, Lap.CREATOR); //error after this line
in.readTypedList(loggedLocations, Location.CREATOR);
startTime = (Date)in.readSerializable();
bestLap = in.readParcelable(Lap.class.getClassLoader());
track = in.readParcelable(Track.class.getClassLoader());
description = in.readString();
}
Here are the other classes:
public class Lap implements Parcelable
{
private ArrayList<Time> sectorTimes = new ArrayList<Time>();
private Time laptime; ...
...
public void writeToParcel(Parcel out, int flags)
{
out.writeTypedList(sectorTimes);
out.writeParcelable(laptime,flags);
}
public static final Parcelable.Creator<Lap> CREATOR = new Parcelable.Creator<Lap>()
{
public Lap createFromParcel(Parcel in)
{
return new Lap(in);
}
public Lap[] newArray(int size)
{
return new Lap[size];
}
};
private Lap(Parcel in)
{
in.readTypedList(sectorTimes, Time.CREATOR);
laptime = in.readParcelable(Time.class.getClassLoader());
}
And this class:
public class Time implements Parcelable
{
private long timeLong;
private String timeString;...
...
public void writeToParcel(Parcel out, int flags)
{
out.writeLong(timeLong);
out.writeString(timeString);
}
public static final Parcelable.Creator<Time> CREATOR = new Parcelable.Creator<Time>()
{
public Time createFromParcel(Parcel in)
{
return new Time(in);
}
public Time[] newArray(int size)
{
return new Time[size];
}
};
private Time(Parcel in)
{
timeLong = in.readLong();
timeString = in.readString();
}
Like I already said, everything works fine (there are more Parcelable classes which I pass with intents (including a single ArrayList) and which I save in files).
So can you guys help me to write and read that double ArrayList?
Thanks in advance
If your code is as posted, then you're just missing the initialization of the ArrayLists, i.e.
private Timetable(Parcel in)
{
// readTypeList() needs an existing List<> to load.
timetable = new ArrayList<Lap>();
loggedLocations = new ArrayList<Location>();
actLap = in.readInt();
in.readTypedList(timetable, Lap.CREATOR);
in.readTypedList(loggedLocations, Location.CREATOR);
...
I have a class like this..
public static class FlightInfoDetails {
static String FlightNumber;
static String DepartureDate;
static String DepartureTime;
public static void setFlightNumber(String pstrData) {
FlightNumber= pstrData;
}
public static void setDepartureDate(String pstrData) {
DepartureDate = pstrData;
}
public static void setDepartureTime(String pstrData) {
DepartureTime = pstrData;
}
public static String getFlightNumber()
{
return FlightNumber;
}
public static String getDepartureDate()
{
return DepartureDate;
}
}
And so on. Everything was fine up to this, but now I need to deal with multiple number of
FlightInfoDetails. When I tried to call that set method the previous data gets lost. Can anybody help?
First off, if you want to be able to create many instances of the FlightInfoDetails class, you should get rid of the static modifiers you have.
public class FlightInfoDetails {
String FlightNumber;
String DepartureDate;
String DepartureTime;
public void setFlightNumber(String pstrData) {
FlightNumber= pstrData;
}
public void setDepartureDate(String pstrData) {
DepartureDate = pstrData;
}
public void setDepartureTime(String pstrData) {
DepartureTime = pstrData;
}
public String getFlightNumber()
{
return FlightNumber;
}
public String getDepartureDate()
{
return DepartureDate;
}
}
Now you shouldn't have any issues creating more than one FlightInfoDetails object, or setting the data for each object. In a main method, you can create an ArrayList of these objects.
public static void main(String [] args)
{
ArrayList<FlightInfoDetails> flightList = new ArrayList<FlightInfoDetails>():
FlightInfoDetails info = new FlightInfoDetails();
flightList.add(info);
FlightInfoDetails info2 = new FlightInfoDetails();
flightList.add(info2);
info.setDepartureDate("May 20, 2013");
info2.setDepartureDate("June 10, 2013");
}
Add a new instance of your FlightInfoDetails class.
FlightInfoDetails details = new FlightInfoDetails();
Call setter methods as necessary on this instance.
details.setDepartureDate("12/12/2013");
Store this instance in a List:
List<FlightInfoDetails> detailsList = new ArrayList<FlightInfoDetails>();
detailsList.add(details);
Note: Ensure you remove all static modifiers from your FlightInfoDetails class so that you can create instances of this class.
In my main class, I have a static method which I pass the array into. It is a static method because if I want to pass something from the main class body to this method, it must be static. In a separate class I have a series of getters and setters (which must be non static ).
How can I pass my static array in and use the non-static getters and setters?
EDIT- In the arraySearch method...I cannot pass in the Person Array and access the getters in the Person Class
public class Main {
public static void main(String[] args) {
Person One = new Person("Alice","Foo", 22, false);
Person Two = new Person("Alice", "Foo",22, false);
Person Three = new Person("Bob","Bar",99, false);
Person Four = new Person("Joe","Blogs",64, false);
Person Five = new Person("Jane", "Joe",42, false);
Person [] People = {One,Two,Three,Four,Five};
printArray(People);
}
public static void printArray(Person [] People)
{
for(int i=0;i<People.length;i++)
{
System.out.println(People[i]);
}
}
public void arraySearch(Person [] People)
{
for(int i=0;i<People.length;i++) //Searches the Array of Objects
{
String firstName = Person.getFirstName();
String secondName=Person.getSecondName();
if((firstName.equals("Joe")&&secondName.equals("B" + //Searches for Joe Blogs and Jane Joe
"logs"))|| ((firstName.equals("Ja" +
"ne")&&secondName.equals("Joe"))))
{
int age=Person.getAge();
Person.setAge(age+1); //Increments Age by 1
}
}
}
}
public class Person {
private String mfirstName;
private String msecondName;
private int mage;
private boolean misRetired;
public Person(String firstName,String secondName,int age, boolean isRetired)
{
mfirstName=firstName;
msecondName=secondName;
mage=age;
misRetired=isRetired;
}
//GETTERS
public String getFirstName()
{
return mfirstName;
}
public String getSecondName()
{
return msecondName;
}
public int getAge()
{
return mage;
}
public boolean getRetired()
{
return misRetired;
}
//SETTERS
public void setFirstName(String firstName)
{
mfirstName=firstName;
}
public void setSecondName(String secondName)
{
msecondName=secondName;
}
public void setAge(int age)
{
mage=age;
}
public void setRetired(boolean isRetired)
{
misRetired=isRetired;
}
//STRING
public String toString()
{
return (mfirstName+"-"+msecondName+"-"+mage+"-"+misRetired);
}
}
This is very basic Java question. You need to create instance of object containing setter/getters from your static method. You can also pass static array in setter of this object. Then you should be able to call those getter/setter methods.
public class Main
{
public static void main(String[] args)
{
MyClass myclass = new MyClass();
myclass.setArgs(args);
System.out.println(myclass.getArgs());
}
}
public class MyClass
{
private String[] args;
public String[] getArgs()
{
return args;
}
public void setArgs(String[] args)
{
this.args= args;
}
}
You have to create an object instance from the class with the getters.
The Amit answer is correct; this just has some more info and more closely matches the situation you describe in your question.
Your basic premise "It is a static method because if I want to pass something from the main class body to this method, it must be static." is wrong. The method to which you pass the array does not need to be static. Here is some code:
public final class Main
{
private static final String[] staticOTron =
{
"one",
"two",
"three"
};
public static void main(final String[] args)
{
String[] hootBerrySause;
Tool tool = new Tool();
tool.setStaticOTron(staticOTron);
hootBerrySause = tool.getStaticOTron();
for (String value : hootBerrySause)
{
System.out.println("Value: " + value);
}
}
}
// this can be in a different file.
public final class Tool
{
private static String[] staticOTron;
public void setStaticOTron(final String[] newValue)
{
staticOTron = newValue;
}
public String[] getStaticOTron()
{
return staticOTron;
}
}
Sunil kumar from vmoksha
Your asking deeper navigation
Just create the instance of particular or create the getter &and setter in the main
class
I have seen many parcelable examples so far, but for some reason I can't get it to work when it gets a bit more complex.
I have a Movie object, which implements Parcelable. This book object contains some properties, such as ArrayLists.
Running my app results in a NullPointerException when executing the ReadTypedList ! I'm really out of ideas here
public class Movie implements Parcelable{
private int id;
private List<Review> reviews
private List<String> authors;
public Movie () {
reviews = new ArrayList<Review>();
authors = new ArrayList<String>();
}
public Movie (Parcel in) {
readFromParcel(in);
}
/* getters and setters excluded from code here */
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(id);
dest.writeList(reviews);
dest.writeStringList(authors);
}
public static final Parcelable.Creator<Movie> CREATOR = new Parcelable.Creator<Movie>() {
public MoviecreateFromParcel(Parcel source) {
return new Movie(source);
}
public Movie[] newArray(int size) {
return new Movie[size];
}
};
/*
* Constructor calls read to create object
*/
private void readFromParcel(Parcel in) {
this.id = in.readInt();
in.readTypedList(reviews, Review.CREATOR); /* NULLPOINTER HERE */
in.readStringList(authors);
}
}
The Review class:
public class Review implements Parcelable {
private int id;
private String content;
public Review() {
}
public Review(Parcel in) {
readFromParcel(in);
}
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(id);
dest.writeString(content);
}
public static final Creator<Review> CREATOR = new Creator<Review>() {
public Review createFromParcel(Parcel source) {
return new Review(source);
}
public Review[] newArray(int size) {
return new Review[size];
}
};
private void readFromParcel(Parcel in) {
this.id = in.readInt();
this.content = in.readString();
}
}
I would be very grateful if someone could just get me on the right track, I have spend quite a bit of time searching for this one !
Thanks in adnvance
Wesley
reviews and authors are both null. You should first initialize the ArrayList. One way to do this is chain the constructor:
public Movie (Parcel in) {
this();
readFromParcel(in);
}
From the javadocs for readTypedList:
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 wrote them with a plain
dest.writeList(reviews);