java.lang.ClassCastException while sending Parcelable[] as Intent extra - android

I am sending an array of TutorAccount as an intent extra to another Activity. Here are the TutorAccount and Account classes involved:
public class TutorAccount extends Account{
public TutorAccount(TutorProfile profile) {
super(profile);
}
public TutorAccount(TutorProfile profile, LocationInfo locationInfo) {
super(profile, locationInfo);
}
public TutorProfile getProfile() {
return (TutorProfile) super.getProfile();
}
public void setProfile(TutorProfile profile) {
super.setProfile(profile);
}
}
and the Account class,
public class Account implements Parcelable {
/**Email Id of the User */
private String mEmailID;
/**Important to have the status indexed as this shall be used during a query for a particular user type*/
private Integer accountStatus;
// Profile info.
private GenericLearnerProfile profile;
// Tutor's location info. - this would be computed from {Latitude, Longitude} which shall be available
// from the _1 info. Also, this holds a reference to the LatLng{Latitude, Longitude} from the _1.
private LocationInfo locationInfo;
public Account(GenericLearnerProfile profile) {
if(profile == null){
throw new NullPointerException("Profile can't be null");
}
this.profile = profile;
mEmailID = profile.getEmailID();
// Auto boxing
this.accountStatus = profile.getCurrentStatus();
}
public Account(GenericLearnerProfile profile, LocationInfo locationInfo) {
if(profile == null){
throw new NullPointerException("Profile can't be null");
}
this.profile = profile;
this.locationInfo = locationInfo;
mEmailID = profile.getEmailID();
this.accountStatus = profile.getCurrentStatus();
}
private Account(){
}
public GenericLearnerProfile getProfile() {
return profile;
}
public void setProfile(GenericLearnerProfile profile) {
if(profile == null){
throw new NullPointerException("Profile can't be null");
}
this.profile = profile;
mEmailID = profile.getEmailID();
}
public LocationInfo getLocationInfo() {
return locationInfo;
}
public void setLocationInfo(LocationInfo locationInfo) {
this.locationInfo = locationInfo;
}
public static class LocationInfo implements Parcelable {
private String shortFormattedAddress;
public LocationInfo(String shortFormattedAddress) {
this.shortFormattedAddress = shortFormattedAddress;
}
public String getShortFormattedAddress() {
return shortFormattedAddress;
}
public void setShortFormattedAddress(String shortFormattedAddress) {
this.shortFormattedAddress = shortFormattedAddress;
}
protected LocationInfo(Parcel in) {
shortFormattedAddress = in.readString();
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(shortFormattedAddress);
}
#SuppressWarnings("unused")
public static final Parcelable.Creator<LocationInfo> CREATOR = new Parcelable.Creator<LocationInfo>() {
#Override
public LocationInfo createFromParcel(Parcel in) {
return new LocationInfo(in);
}
#Override
public LocationInfo[] newArray(int size) {
return new LocationInfo[size];
}
};
}
protected Account(Parcel in) {
mEmailID = in.readString();
accountStatus = in.readByte() == 0x00 ? null : in.readInt();
profile = (GenericLearnerProfile) in.readValue(GenericLearnerProfile.class.getClassLoader());
locationInfo = (LocationInfo) in.readValue(LocationInfo.class.getClassLoader());
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(mEmailID);
if (accountStatus == null) {
dest.writeByte((byte) (0x00));
} else {
dest.writeByte((byte) (0x01));
dest.writeInt(accountStatus);
}
dest.writeValue(profile);
dest.writeValue(locationInfo);
}
#SuppressWarnings("unused")
public static final Parcelable.Creator<Account> CREATOR = new Parcelable.Creator<Account>() {
#Override
public Account createFromParcel(Parcel in) {
return new Account(in);
}
#Override
public Account[] newArray(int size) {
return new Account[size];
}
};
}
You can see that TutorAccount extends Account. Here is the stack trace of the exception:
java.lang.ClassCastException: com.learncity.generic.learner.account.Account cannot be cast to com.learncity.tutor.account.TutorAccount
at com.learncity.learner.search.SearchResultsActivity.onCreate(SearchResultsActivity.java:48)
at android.app.Activity.performCreate(Activity.java:6662)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2599)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2707) 
at android.app.ActivityThread.-wrap12(ActivityThread.java) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:154) 
at android.app.ActivityThread.main(ActivityThread.java:6077) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755) 
It is saying Account cannot be casted to TutorAccount. I am not sure how Account even came into casting scenarion as it is supposed to be Parcelable to TutorAccount cast.
Here is the code used to send and receive the Intent extra:
Sending Activity
// Show these accounts in a list view
Intent i = new Intent(this, SearchResultsActivity.class);
i.putExtra(SEARCHED_ACCOUNTS, refactorAccountsToArray(accounts));
startActivity(i);
Receiving Activity
List<TutorAccount> list = new ArrayList<>(10);
for(Parcelable p : getIntent ().getParcelableArrayExtra(SEARCHED_ACCOUNTS)){
list.add((TutorAccount)p);
}
I have tried Logging the p - the Parcelable in the receiving activity and it shows it being an instance of Account. I am not sure how this is happening. Has anyone faced this?
EDIT:
The List<TutorAccount> accounts that I am receiving in the argument here is a different class to model backend JSON data.
Here is the refactorAccountsToArray() method:
private List<com.learncity.tutor.account.TutorAccount> refactorAccountsToList(List<TutorAccount> accounts){
// Extract the list of accounts from backend
List<TutorProfileVer1> profiles = new ArrayList<TutorProfileVer1>();
List<Account.LocationInfo> locationInfos = new ArrayList<Account.LocationInfo>();
for(TutorAccount acc : accounts){
profiles.add(acc.getProfile());
locationInfos.add(new Account.LocationInfo((acc.getLocationInfo() == null ? null: acc.getLocationInfo().getShortFormattedAddress())));
}
// Populate a profile model
List<com.learncity.tutor.account.TutorAccount> acc = new ArrayList<com.learncity.tutor.account.TutorAccount>();
List<TutorProfile> refactoredProfiles = TutorProfile.populateProfilesFromEntities(profiles);
int i = 0;
for(TutorProfile p : refactoredProfiles){
com.learncity.tutor.account.TutorAccount t = new com.learncity.tutor.account.TutorAccount(p);
t.setLocationInfo(new Account.LocationInfo(locationInfos.get(i).getShortFormattedAddress()));
acc.add(t);
i++;
}
return acc;
}
private com.learncity.tutor.account.TutorAccount[] refactorAccountsToArray(List<TutorAccount> accounts){
List<com.learncity.tutor.account.TutorAccount> refactoredProfiles = refactorAccountsToList(accounts);
return refactoredProfiles.toArray(new com.learncity.tutor.account.TutorAccount[refactoredProfiles.size()]);
}

As per the advice by #AnhaytAnanun Turns out that for even a cast, a creator is required for a Parcelable entity. My code works now with the inclusion of CREATOR and other Parcelable methods. Here is the revised code:
package com.learncity.tutor.account;
import android.os.Parcel;
import android.os.Parcelable;
import com.learncity.generic.learner.account.Account;
import com.learncity.tutor.account.profile.model.TutorProfile;
/**
* Created by DJ on 3/7/2017.
*/
public class TutorAccount extends Account{
public TutorAccount(TutorProfile profile) {
super(profile);
}
public TutorAccount(TutorProfile profile, LocationInfo locationInfo) {
super(profile, locationInfo);
}
public TutorProfile getProfile() {
return (TutorProfile) super.getProfile();
}
public void setProfile(TutorProfile profile) {
super.setProfile(profile);
}
public TutorAccount(Parcel in) {
super(in);
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
}
#SuppressWarnings("unused")
public static final Parcelable.Creator<TutorAccount> CREATOR = new Parcelable.Creator<TutorAccount>() {
#Override
public TutorAccount createFromParcel(Parcel in) {
return new TutorAccount(in);
}
#Override
public TutorAccount[] newArray(int size) {
return new TutorAccount[size];
}
};
}

Related

Firebase real database values differ from the retrieved ones

So, in realtime database I have:
When I retrieve data from database I get:
Model class looks like:
public class User implements Parcelable {
public static final Parcelable.Creator<User> CREATOR = new Parcelable.Creator<User>() {
#Override
public User createFromParcel(Parcel source) {
return new User(source);
}
#Override
public User[] newArray(int size) {
return new User[size];
}
};
...
private String hasToPayFromPastRides;
private String didNotPayCount;
...;
public User() {
}
public User(..., String didNotPayCount, String hasToPayFromPastRides) {
...
this.didNotPayCount = didNotPayCount;
this.hasToPayFromPastRides = hasToPayFromPastRides;
}
protected User(Parcel in) {
...
this.didNotPayCount = in.readString();
this.hasToPayFromPastRides = in.readString();
}
...
public String getDidNotPayCount() {
return didNotPayCount;
}
public void setDidNotPayCount(String didNotPayCount) {
this.didNotPayCount = didNotPayCount;
}
public String hasToPayFromPastRides() {
return hasToPayFromPastRides;
}
public void setHasToPayFromPastRides(String hasToPayFromPastRides) {
this.hasToPayFromPastRides = hasToPayFromPastRides;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.userId);
dest.writeString(this.userFullName);
dest.writeString(this.userEmail);
dest.writeString(this.userPhoneNumber);
dest.writeString(this.userAvatarUrl);
dest.writeString(this.userLocalAvatar);
dest.writeString(this.userAddress);
dest.writeString(this.userCity);
dest.writeString(this.userArea);
dest.writeString(this.userPostalCode);
dest.writeString(this.userRating);
dest.writeString(this.userTotalRating);
dest.writeString(this.totalTrips);
dest.writeString(this.riskCount);
dest.writeString(this.isBlocked);
dest.writeString(this.isDefaulter);
dest.writeString(this.pendingRating);
dest.writeParcelable(this.pendingRateObj, flags);
dest.writeString(this.didNotPayCount);
dest.writeString(this.hasToPayFromPastRides);
}
}
What surprises me is that one value gets read correctly "didNotPayCount" when "hasToPayFromPastRides" is null. Any ideas?
Your getter isn't named correctly:
public String hasToPayFromPastRides()
It should be:
public String getHasToPayFromPastRides()

How to send ArrayList<Object> to other Fragment/Activity without init (start) the next Activity?

I have an ArrayList and I need to send it to another fragment. I tried to use Parcelable, but to send the data I need the "startIntent" method which starts the fragment. I don't want the fragment to be started.
I need send data array list object to another fragment without going to this other fragment. I only need to send the data. The user is free to chose when to change between activities/fragments. And the data sent earlier should already be there.
Example using Parcelable:
Class that must be to sent:
import android.os.Parcel;
import android.os.Parcelable;
public class Doenca implements Parcelable {
private String nome;
private String causa;
private String efeito;
private String cuidados;
private String prevencao;
private String categoria;
public Doenca(String nome, String causa, String efeito, String cuidados, String prevencao, String categoria) {
this.nome = nome;
this.causa = causa;
this.efeito = efeito;
this.cuidados = cuidados;
this.prevencao = prevencao;
this.categoria = categoria;
}
protected Doenca(Parcel in) {
nome = in.readString();
causa = in.readString();
efeito = in.readString();
cuidados = in.readString();
prevencao = in.readString();
categoria = in.readString();
}
public static final Creator<Doenca> CREATOR = new Creator<Doenca>() {
#Override
public Doenca createFromParcel(Parcel in) {
return new Doenca(in);
}
#Override
public Doenca[] newArray(int size) {
return new Doenca[size];
}
};
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public String getCausa() {
return causa;
}
public void setCausa(String causa) {
this.causa = causa;
}
public String getEfeito() {
return efeito;
}
public void setEfeito(String efeito) {
this.efeito = efeito;
}
public String getCuidados() {
return cuidados;
}
public void setCuidados(String cuidados) {
this.cuidados = cuidados;
}
public String getPrevencao() {
return prevencao;
}
public void setPrevencao(String prevencao) {
this.prevencao = prevencao;
}
public String getCategoria() {
return categoria;
}
public void setCategoria(String categoria) {
this.categoria = categoria;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(nome);
dest.writeString(causa);
dest.writeString(efeito);
dest.writeString(cuidados);
dest.writeString(prevencao);
dest.writeString(categoria);
}
}
import android.os.Parcel;
import android.os.Parcelable;
public class Doenca implements Parcelable {
private String nome;
private String causa;
private String efeito;
private String cuidados;
private String prevencao;
private String categoria;
public Doenca(String nome, String causa, String efeito, String cuidados, String prevencao, String categoria) {
this.nome = nome;
this.causa = causa;
this.efeito = efeito;
this.cuidados = cuidados;
this.prevencao = prevencao;
this.categoria = categoria;
}
protected Doenca(Parcel in) {
nome = in.readString();
causa = in.readString();
efeito = in.readString();
cuidados = in.readString();
prevencao = in.readString();
categoria = in.readString();
}
public static final Creator<Doenca> CREATOR = new Creator<Doenca>() {
#Override
public Doenca createFromParcel(Parcel in) {
return new Doenca(in);
}
#Override
public Doenca[] newArray(int size) {
return new Doenca[size];
}
};
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public String getCausa() {
return causa;
}
public void setCausa(String causa) {
this.causa = causa;
}
public String getEfeito() {
return efeito;
}
public void setEfeito(String efeito) {
this.efeito = efeito;
}
public String getCuidados() {
return cuidados;
}
public void setCuidados(String cuidados) {
this.cuidados = cuidados;
}
public String getPrevencao() {
return prevencao;
}
public void setPrevencao(String prevencao) {
this.prevencao = prevencao;
}
public String getCategoria() {
return categoria;
}
public void setCategoria(String categoria) {
this.categoria = categoria;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(nome);
dest.writeString(causa);
dest.writeString(efeito);
dest.writeString(cuidados);
dest.writeString(prevencao);
dest.writeString(categoria);
}
}
There are multiple ways with different complexity for the implementation.
Use a database to store what you need there
Store the data in the host activity containing the tabs. As soon as you switch the fragment, all you need to do is read the data from the place where you have stored it.
Use LiveData. LiveData would be my personal preference. There you can easily store any data you need and the second fragment simply observes the livedata and can easily react to changes. So you could even switch in both directions as often as you want to.
Try Using EventBus.
To use EventBus, you need to first add it to in the app module build.gradle file
implementation 'org.greenrobot:eventbus:3.1.1'
and then sync your project.
An Event Subscriber
A subscriber simply subscribes to an event by registering in the event bus and can also unregister that event. To be a subscriber, you have to do three main things:
Register the subscriber in the event bus with register(). This informs the event bus that you want to begin receiving events. In an activity, this is in the onStart() method, while in a fragment put this in the onAttact(Activity activity) method.
#Override
public void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
Unregister the subscriber, which means tell the event bus to stop sending me events. In an activity, this is in the onStop() method, while in a fragment put this in the onDetach() method.
#Override
public void onStop() {
super.onStop();
EventBus.getDefault().unregister(this);
}
Implement the onEvent() to indicate the type of event you want to receive and action to take when you receive the event. Notice the #Subscribe annotation at the top of this method.
#Subscribe
public void onEvent(MessageEvent event) {
Toast.makeText(this, "Hey, my message" + event.getMessage(),
Toast.LENGTH_SHORT).show();.
}
Defining Event Messages
The events in greenrobot EventBus are just objects that you define. You can have different event classes if you want. They do not inherit any base class or interface—they're just POJO (Plain Old Java Objects).
public class MessageEvent {
public final List<SomeItem> items;
public MessageEvent(List<SomeItem> items) {
this.items= items;
}
}
Post Event
EventBus.getDefault().post(new MessageEvent("Hey event subscriber!"));

How to populate values to variables of a parcelable class whose object we are sending from one activity to the other

Stack trace:
11-16 20:39:42.374 30640-30703/? E/LocalFingerprints: cannot compute fingerprint for: content://media/external/images/media/41373
java.io.FileNotFoundException: No such file or directory
at android.database.DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(DatabaseUtils.java:146)
at android.content.ContentProviderProxy.openTypedAssetFile(ContentProviderNative.java:682)
at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:1063)
at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:904)
at android.content.ContentResolver.openInputStream(ContentResolver.java:629)
at cak.a(PG:159)
at bzj.a(PG:123)
at com.google.android.apps.plus.service.FingerprintScannerIntentService.onHandleIntent(PG:79)
at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.os.HandlerThread.run(HandlerThread.java:61)
This is the FirstActivity:
void handleBlogEditClick(){
if (BlogDetailActivity.this!= null) {
BlogDetailVO blogDetailVO=new BlogDetailVO(getArgs().getmId(),getArgs().getmName().toString(),getArgs().getmDescription().toString());
blogDetailVO.mCoverPic.setmImageUrl(getArgs().getmImageUrl());
Intent intent = new Intent(BlogDetailActivity.this, EditBlogActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
intent.putExtra("blogDetailVO",blogDetailVO);
startActivity(intent);
}
}
Second activity:
mState = new EditBlogState();
Intent intent = getIntent();
BlogDetailVO blogDetailVO =(BlogDetailVO) intent.getParcelableExtra("blogDetailVO");
mState.mCoverPhotoStory.setmName(blogDetailVO.getmName());
mView.updateBlogTitle(mState.mCoverPhotoStory.getmName());
Other things in the first and second activity code is irrelevant to this so i shared this much
public class BlogDetailVO extends BlogFeedVO implements Parcelable{
PhotoStoryVO mCoverPic;
List<PhotoStoryVO> mPhotoStories;
LocationVO mLocationVO;
public BlogDetailVO(String mId, String mName, String mDescription) {
super(mId, mName, mDescription);
}
protected BlogDetailVO(Parcel in) {
super(in);
mCoverPic = in.readParcelable(PhotoStoryVO.class.getClassLoader());
mPhotoStories = in.createTypedArrayList(PhotoStoryVO.CREATOR);
mLocationVO = in.readParcelable(LocationVO.class.getClassLoader());
}
#Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeParcelable(mCoverPic, flags);
dest.writeTypedList(mPhotoStories);
dest.writeParcelable(mLocationVO, flags);
}
#Override
public int describeContents() {
return hashCode();
}
public static final Creator<BlogDetailVO> CREATOR = new Creator<BlogDetailVO>() {
#Override
public BlogDetailVO createFromParcel(Parcel in) {
return new BlogDetailVO(in);
}
#Override
public BlogDetailVO[] newArray(int size) {
return new BlogDetailVO[size];
}
};
public PhotoStoryVO getmCoverPic() {
return mCoverPic;
}
public void setmCoverPic(PhotoStoryVO mCoverPic) {
this.mCoverPic = mCoverPic;
}
public List<PhotoStoryVO> getmPhotoStories() {
return mPhotoStories;
}
public void setmPhotoStories(List<PhotoStoryVO> mPhotoStories) {
this.mPhotoStories = mPhotoStories;
}
public LocationVO getmLocationVO() {
return mLocationVO;
}
public void setmLocationVO(LocationVO mLocationVO) {
this.mLocationVO = mLocationVO;
}
}
I am new to android. so sorry if the question is silly. But i am really stuck and need help. i am sending BlogDetailVO class object to another activity. The second line is showing null. so can't i populate value in this way? Eventually it crashes.
BlogDetailVO blogDetailVO=new BlogDetailVO(getArgs().getmId(),getArgs().getmName().toString(),getArgs().getmDescription().toString());
blogDetailVO.mCoverPic.setmImageUrl(getArgs().getmImageUrl()); //this gives the error!!
Intent intent = new Intent(BlogDetailActivity.this, EditBlogActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
intent.putExtra("blogDetailVO",blogDetailVO); startActivity(intent);
So how to populate values to BlogDtailVO class so to send it to the other activity?
In the receiving activity I am receiving it this way:
Intent intent = getIntent();
BlogDetailVO blogDetailVO =(BlogDetailVO) intent.getParcelableExtra("blogDetailVO");

Android: passing object between activities and make it parcelable

New to Android programming. Having trouble to pass the object between activities and make it parcelable. Could somebody tell me what the problem could be? I want to know whether the logic is sound.
public class MainActivity extends Activity {
private Bundle MyActivityParams;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = new Intent(this, MyActivity.class);
MyActivityParams = fillInData(MyActivityParams);
intent.putExtras(MyActivityParams);
startActivity(intent, savedInstanceState);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
private Bundle fillInData(Bundle bundle){
bundle.putFloat("com.company.MyActivity.FL", 12);
bundle.putFloat("com.company.MyActivity.VH", 100);
bundle.putFloat("com.company.MyActivity.const", 1);
return bundle;
}
}
public class DisplayActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
displayData();
}
private void displayData(){
//ActivityData is from MyActivity
ActivityData data = new ActivityData(getIntent().getExtras());
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_display, menu);
return true;
}
}
public class MyActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
displayParams();
}
private void displayParams(){
ActivityData dataBundle = new ActivityData((getIntent()).getExtras());
transfer(dataBundle);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_algorithm, menu);
return true;
}
public void transfer(ActivityData incomingdata){
startActivity(incomingdata.getIntent());
}
protected static class ActivityData{
private Bundle data;
private TextView text;
private Intent intent;
public ActivityData(Bundle bundle){
/*data = bundle;
intent = new Intent(null, DisplayActivity.class);
text = new TextView(null);*/
}
public void display(String key){
this.text.setText(data.getString(key));
//not allowed: startActivity(intent);
//not allowed either: setContentView(text);
}
public Intent getIntent() {
return intent;
}
public void setIntent(Intent intent) {
this.intent = intent;
}
public TextView getText() {
return text;
}
public void setText(TextView text) {
this.text = text;
}
public Bundle getData() {
return data;
}
public void setData(Bundle data) {
this.data = data;
}
}
}
Let's have a Person class
public class Person {
private String name;
private String email;
private int age;
public Person(int age, String name, String email) {
this.age = age;
this.name = name;
this.email = email;
}
}
A parcelable one would look like this
public class ParcelablePerson implements Parcelable {
private final Person person;
private ParcelablePerson(Parcel parcel) {
this.person = new Person(parcel.readInt(), parcel.readString(), parcel.readString());
}
public ParcelablePerson(Person person) {
this.person = person;
}
public Person getPerson() {
return person;
}
#Override
public int describeContents() {
return 0;
}
// This is the method where you disassembly your object to pieces
#Override
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeInt(person.getAge());
parcel.writeString(person.getName());
parcel.writeString(person.getEmail());
}
public static final Creator<ParcelablePerson> CREATOR = new Creator<ParcelablePerson>() {
// And here you create a new instance from a parcel using the first constructor
#Override
public ParcelablePerson createFromParcel(Parcel parcel) {
return new ParcelablePerson(parcel);
}
#Override
public ParcelablePerson[] newArray(int size) {
return new ParcelablePerson[size];
}
};
}
The crucial thing in the process is to have the same order of the variables in private ParcelablePerson(Parcel parcel) constructor and public void writeToParcel(Parcel parcel, int flags) method... You can see it on the age property which is an int.
try this one.
ParcelTest.java
import java.util.HashMap;
import android.os.Parcel;
import android.os.Parcelable;
public class ParcelTest implements Parcelable {
private HashMap map;
public ParcelTest() {
map = new HashMap();
}
public ParcelTest(Parcel in) {
map = new HashMap();
readFromParcel(in);
}
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
public ParcelTest createFromParcel(Parcel in) {
return new ParcelTest(in);
}
public ParcelTest[] newArray(int size) {
return new ParcelTest[size];
}
};
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(map.size());
for (String s: map.keySet()) {
dest.writeString(s);
dest.writeString(map.get(s));
}
}
public void readFromParcel(Parcel in) {
int count = in.readInt();
for (int i = 0; i < count; i++) {
map.put(in.readString(), in.readString());
}
}
public String get(String key) {
return map.get(key);
}
public void put(String key, String value) {
map.put(key, value);
}
}
ExampleSupplierActivity.java
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
public class ExampleSupplierActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ParcelTest p = new ParcelTest();
p.put("green", "go");
p.put("yellow", "wait");
p.put("red", "stop");
Bundle b = new Bundle();
b.putParcelable("com.example.trafficlight", p);
Intent i = new Intent(this, ExampleConsumerActivity.class);
i.putExtras(b);
startActivity(i);
}
}
ExampleConsumerActivity.java
import android.app.Activity;
import android.os.Bundle;
public class ExampleConsumerActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle b = getIntent().getExtras();
ParcelTest p = b.getParcelable("com.example.trafficlight");
String red = p.get("red");
// ...
}
}
try this out this code work for me. but i have implement serializable rather than parcelable.
Try to implement parcelable rather than serializable . and try it if its work. i havnt tried this but implementing parcelable.
To pass and object to another activity:
in activity A
make sure the class implements the serializable interface
create a new intent
create a new bundle
use the putSerializeable method to add the object to the bundle with a key
put the bundle in the intent by using the putExtras method
start the activity using the startActivity method
Specifically,
Intent intent = new Intent(ShoulderExerciseScreen.this, ExercisesScreen.class);
Bundle bundle = new Bundle();
bundle.putSerializable("exercise", new Exercise("BenchPress));
intent.putExtras(bundle);
startActivity(intent);
in activity B
declare and object of the type you want passed
use the getIntent method to get the intent
use the getSerializeableExtra to get the the value using the key
cast the returned value from getSerializeableExtra and the desired type
Specifically,
Exercise ex = (Exercise)getIntent().getSerializableExtra("exercise");
if(ex != null)
{
//do something
}

Passing ArrayLists in Android

I'm trying to pass array lists between activities in Android. The lists contains strings. I've read a lot about Parcelable. Would I need to create a Parcelable to pass a String array list? As of now I am using putStringArrayListExtra() and getSringArrayListExtra() to pass the lists through intents.
Here is some of my code.
Intent load = new Intent(getApplicationContext(), HelloTabWidget.class);
load.putStringArrayListExtra("albums", albums);
load.putStringArrayListExtra("songs", songs);
load.putStringArrayListExtra("artists", artists);
load.putStringArrayListExtra("fileName", fileName);
This is my onCreate method for the acticity which obtains the array list.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.songlist);
Bundle extras = getIntent().getExtras();
isArtists = extras.getBoolean("artists");
isAlbums = extras.getBoolean("albums");
isSongs = extras.getBoolean("songs");
Intent get = getIntent();
songs = get.getStringArrayListExtra("songs");
artists = get.getStringArrayListExtra("artists");
albums = get.getStringArrayListExtra("albums");
fileName = get.getStringArrayListExtra("fileName");
if(isArtists == true)
updateArtistsList();
else if(isAlbums == true)
updateAlbumsList();
else if(isSongs == true)
updateSongList();
}
The class which retrieves the list is supposed to create a listView from the data in the lists. Whenever I run the code i get nullPointerExceptions when trying to make the lists. I know that my listView code works, so I have narrowed down the problem to the intents which pass the array lists.
Thanks in advance.
EDIT:
Here are the first few lines from the logcat.
12-28 03:03:42.313: E/AndroidRuntime(873): FATAL EXCEPTION: main
12-28 03:03:42.313: E/AndroidRuntime(873): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.adam.mediaplayer/com.adam.mediaplayer.HelloTabWidget}: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.adam.mediaplayer/com.adam.mediaplayer.MakeListActivity}: java.lang.NullPointerException
It depends on the type of arraylist
putIntegerArrayListExtra(String name, ArrayList<Integer> value)
putParcelableArrayListExtra(String name, ArrayList<? extends Parcelable> value)
putStringArrayListExtra(String name, ArrayList<String> value)
putCharSequenceArrayListExtra(String name, ArrayList<CharSequence> value)
Then you can read from you next activity by replacing put with get with key string as argument,eg
myIntent.getStringArrayListExtra("arrayListName");
Here is how you can pass an ArrayList :
MyListClass.java - Custom class
public class MyListClass implements Parcelable{
private int test;
public MyListClass()
{}
public MyListClass(Parcel read){
test = read.readInt();
}
public int getTest() {
return test;
}
public void setTest(int test) {
this.test = test;
}
public static final Parcelable.Creator<MyListClass> CREATOR =
new Parcelable.Creator<MyListClass>() {
#Override
public MyListClass createFromParcel(Parcel source) {
return new MyListClass(source);
}
#Override
public MyListClass[] newArray(int size) {
return new MyListClass[size];
}
};
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel arg0, int arg1) {
arg0.writeInt(test);
}
}
MyParcelable.java
public class MyParcelable implements Parcelable {
private List<MyListClass> arrList = new ArrayList<MyListClass>();
private int myInt = 0;
private String str = null;
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
}
public List<MyListClass> getArrList() {
return arrList;
}
public void setArrList(List<MyListClass> arrList) {
this.arrList = arrList;
}
public int getMyInt() {
return myInt;
}
public void setMyInt(int myInt) {
this.myInt = myInt;
}
MyParcelable() {
// initialization
arrList = new ArrayList<MyListClass>();
}
public MyParcelable(Parcel in) {
myInt = in.readInt();
str = in.readString();
in.readTypedList(arrList, MyListClass.CREATOR);
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel outParcel, int flags) {
outParcel.writeInt(myInt);
outParcel.writeString(str);
outParcel.writeTypedList(arrList);
}
public static final Parcelable.Creator<MyParcelable> CREATOR = new Parcelable.Creator<MyParcelable>() {
#Override
public MyParcelable createFromParcel(Parcel in) {
return new MyParcelable(in);
}
#Override
public MyParcelable[] newArray(int size) {
return new MyParcelable[size];
}
};
}
MainAcitivty.java
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
arrList.add(new MyListClass());
arrList.get(0).setTest(200);
MyParcelable object = new MyParcelable();
object.setMyInt(100);
object.setArrList(arrList);
Intent intent = new Intent(MainActivity.this,ReceiverParcel.class);
intent.putExtra("parcel", object);
startActivity(intent);
}
ReceiverParcel.java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle b = getIntent().getExtras();
MyParcelable object = b.getParcelable("parcel");
System.out.println(object.getArrList().get(0).getTest());
System.out.println(object.getMyInt());
}

Categories

Resources