0

I have a provider that takes a decent number of properties. For example:

public MyProvider(
  byte[] image,
  String firstName,
  String nickName,
  String lastName,
  String hairColor,
  String favoriteFood,
  String favoriteColor,
  String cityBorn,
  String stateBorn,
  long favoriteNumber,
  int age,
  String nameOfFather,
  String nameOfMother,
  String nameOfBestFriend
)

I do know that I can get the value of each property, and set each individual one as an extra, like so:

Intent myIntent = new Intent(firstActivity.this, secondActivity.class);
myIntent.putExtra("firstName", myProvider.getFirstName().toString());
myIntent.putExtra("nickName", myProvider.getNickName().toString());
...
firstActivity.this.startActivity(myIntent);

I would like to just pass the entire provider as an extra, and then be able to get the provider in the next activity. I know it's possible to do such a thing in Swift, but I am not sure how to do so in Java for Android Studio.

What I am hoping to be able to do is something like the following:

MyProvider newPerson = new MyProvider(image, firstName, nickName, lastName, hairColor, favoriteFood, favoriteColor, cityBorn, stateBorn, favoriteNumber, age, nameOfFather, nameOfMother, nameOfBestFriend);
intent.putExtra(newPerson);

But it seems like a provider cannot be passed like this (or possibly at all?).

Alternative Attempt:

  • I also attempted passing it as data like a URI (see here), but .setData is specifically for URIs.

Is there such a way to pass the entire provider as an extra, and then be able to get the provider in the next activity?

Thanks in advance.


EDIT

I have implemented Parcelable as @NabinBhandari and @JuanCruzSoler suggested, but it is causing the following error:

Cannot resolve constructor 'MyProvider(byte[], java.lang.String, long)'

when I call:

 MyApartmentsProvider newApartment = new MyApartmentsProvider(image, firstName, favoriteNumber); 

My updated MyProvider.java is as follows:

(note: I cut out some variables for the time being to make the example easier to work with)

import android.os.Parcel;
import android.os.Parcelable;

public class MyProvider implements Parcelable {

    /////////////////////////
    // Initializers

    byte[] image;
    String firstName;
    long favoriteNumber;


    // End of [Initializers]
    /////////////////////////

    /////////////////////////
    // Getters

    public byte[] getImage() {
        return image;
    }
    public String getFirstName() {
        return firstName;
    }
    public long getFavoriteNumber() {
        return favoriteNumber;
    }

    // End of [Getters]
    /////////////////////////


    /////////////////////////
    // Setters

    public void setImage(byte[] image) {
        this.image = image;
    }
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
    public void setFavoriteNumber(long favoriteNumber) {
        this.favoriteNumber = favoriteNumber;
    }

    // End of [Setters]
    /////////////////////////


    public MyProvider() {
        super();
    }

    public MyProvider(Parcel parcel) {
        image = new byte[parcel.readInt()];
        parcel.readByteArray(image);
        this.firstName = parcel.readString();
        this.favoriteNumber = parcel.readLong();
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel parcel, int i) {
        parcel.writeInt(image.length);
        parcel.writeByteArray(image);
        parcel.writeString(this.firstName);
        parcel.writeLong(this.favoriteNumber);
    }

    public static final Creator<MyProvider> CREATOR=new Creator<MyProvider>() {
        @Override
        public MyProvider createFromParcel(Parcel parcel) {
            return new MyProvider(parcel);
        }

        @Override
        public MyProvider[] newArray(int i) {
            return new MyProvider[i];
        }
    };
}
Rbar
  • 3,740
  • 9
  • 39
  • 69
  • Your class should implement `Parcelable` and then you can pass it into the Intent – Juan Cruz Soler Oct 06 '17 at 17:37
  • 2
    "then be able to get the provider in the next activity" -- using `Parcelable`, you can get *a copy* of the provider in the next activity (or you might crash, if your `Parcelable` is too big). Or, you could implement a better app architecture, one where both activities can access the provider instance without duplicating it (e.g., a repository with a cache). – CommonsWare Oct 06 '17 at 17:42
  • @CommonsWare, is the same issue true for `Serializable`? – Rbar Oct 06 '17 at 19:00
  • Yes. There is no pass-by-reference in `Intent` extras, for the simple reason that every `startActivity()` call involves IPC, even when the activity calling `startActivity()` and the activity being started happen to be in the same process. – CommonsWare Oct 06 '17 at 19:05
  • Thanks, @CommonsWare. This is helpful to know – Rbar Oct 06 '17 at 19:13

1 Answers1

1

Make your Provider class implement the interface Serializable or Parcelable.

Parcelable is faster but Serializable is easier to implement.

To send:

intent.putExtra(KEY, yourObj);

To receive:

Provider provider = (Provider) getIntent().getSerializableExtra(KEY);
Nabin Bhandari
  • 15,949
  • 6
  • 45
  • 59