【问题标题】:Pass Provider as extra of Intent将 Provider 作为 Intent 的额外内容
【发布时间】:2018-03-18 13:53:06
【问题描述】:

我有一个提供大量属性的提供商。例如:

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
)

我确实知道我可以获取每个属性的值,并将每个单独的属性设置为额外的,如下所示:

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

我想将整个提供程序作为额外的传递,然后能够在下一个活动中获取提供程序。我知道在 Swift 中可以做到这一点,但我不确定如何在 Java for Android Studio 中做到这一点。

我希望能够做的事情如下:

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

但似乎不能像这样传递提供者(或者根本不能传递?)。

替代尝试:

  • 我还尝试将它作为数据传递给 URI (see here),但 .setData 专门用于 URI。

有没有这样的办法,将整个provider作为extra传递,然后能够在下一个activity中获取provider?

提前致谢。


编辑

我已经按照@NabinBhandari 和@JuanCruzSoler 的建议实施了Parcelable,但它导致了以下错误:

无法解析构造函数'MyProvider(byte[], java.lang.String, long)'

当我打电话时:

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

我更新的MyProvider.java如下:

(注意:我暂时删掉了一些变量,以使示例更易于使用)

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];
        }
    };
}

【问题讨论】:

  • 你的类应该实现Parcelable 然后你可以将它传递给Intent
  • "然后能够在下一个活动中获取提供者" -- 使用Parcelable,您可以在下一个活动中获取提供者的副本(或者您如果您的 Parcelable 太大,可能会崩溃)。或者,您可以实现更好的应用架构,其中两个活动都可以访问提供者实例而无需复制它(例如,具有缓存的存储库)。
  • @CommonsWare,Serializable 是否存在同样的问题?
  • 是的。 Intent extras 中没有 pass-by-reference,原因很简单,每个 startActivity() 调用都涉及 IPC,即使调用 startActivity() 的 Activity 和正在启动的 Activity 恰好在同一个进程中。跨度>
  • 谢谢,@CommonsWare。这有助于了解

标签: java android android-intent android-contentprovider extras


【解决方案1】:

让您的Provider 类实现接口SerializableParcelable

Parcelable 更快,但Serializable 更容易实现。

发送:

intent.putExtra(KEY, yourObj);

接收:

Provider provider = (Provider) getIntent().getSerializableExtra(KEY);

【讨论】:

  • 在我们说话的时候尝试实施 Parcelable!
  • 我已经实现了 Parcelable,但是当我尝试初始化一个新的提供者时,它导致了 cannot resolve constructor 的错误。你明白为什么吗?
  • 你可能弄乱了代码,用Serializable就行了,你不需要实现额外的方法..
  • @NabinBhandari 我已经发布了我的代码并缩短了它,以便阅读更少。你介意看看我上面的编辑吗?
  • 我不知道怎么用Parcelable你为什么不直接用Serializable
猜你喜欢
  • 2020-05-30
  • 1970-01-01
  • 1970-01-01
  • 2013-08-04
  • 2011-08-23
  • 2022-05-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多