Java嵌套式包裹,可';不要初始化数组
好的,我已经阅读了几乎每一个关于堆栈溢出的包裹问题,并尝试了许多解决方案来解决这个问题。总的来说,我有一个android项目,我想通过Java嵌套式包裹,可';不要初始化数组,java,android,android-intent,parcelable,Java,Android,Android Intent,Parcelable,好的,我已经阅读了几乎每一个关于堆栈溢出的包裹问题,并尝试了许多解决方案来解决这个问题。总的来说,我有一个android项目,我想通过Intent将2个ArrayLists数组从一个类发送到另一个类 注意:这不是不处理数组的嵌套可包裹线程的副本。它不是的副本,因为我已使所有嵌套类都可打包。它不是或的副本,因为我没有使用数组列表,而且我认识到错误是初始化失败。它不是的副本,因为在这种情况下我不需要无参数构造函数(我已经测试过添加一个构造函数,它不会更改错误)。它也不是的副本,因为它不是嵌套在地块中
Intent
将2个ArrayList
s数组从一个类发送到另一个类
注意:这不是不处理数组的嵌套可包裹线程的副本。它不是的副本,因为我已使所有嵌套类都可打包。它不是或的副本,因为我没有使用数组列表,而且我认识到错误是初始化失败。它不是的副本,因为在这种情况下我不需要无参数构造函数(我已经测试过添加一个构造函数,它不会更改错误)。它也不是的副本,因为它不是嵌套在地块中的地块
我必须做一些显而易见的事情,因为只有在我的数组尚未初始化的情况下才会发生nullpointer错误。但是,在我知道我希望数组长度为多长之前,我不可能初始化数组长度
(作为旁注,也许有人可以让我更深入地了解readTypedList
类以及XXX.Creator
的具体功能,因为这无疑可能是问题的一部分。此外,对于任何未来有同样问题的人来说,还有一个指向包裹
javadoc的链接,它提供了信息,但没有解决我的问题嗯)
现在我有了一个显示对象。该显示对象仅用于存储字符串[]
,并允许对其进行包裹。下面已对与的分隔线进行了注释,对于任何有包裹经验的人来说都应该是显而易见的,因为它显然尚未初始化:
class Display implements Parcelable {
String[] labels;
public Display(String[] labels) {
this.labels = labels;
}
protected Display(Parcel in) {
in.readStringArray(this.labels); // **** THIS LINE BREAKS
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeStringArray(this.labels);
}
@Override
public int describeContents() {
return 0;
}
public static final Creator<Display> CREATOR = new Creator<Display>() {
@Override
public Display createFromParcel(Parcel in) {
return new Display(in);
}
@Override
public Display[] newArray(int size) {
return new Display[size];
}
};
}
因为它是嵌套的,所以调用创建者的方式在很大程度上限制了我的选择,导致我无法解决问题
在各种测试中,我遇到了许多错误,但没有解决方案…(我的代码当前抛出的错误是尝试获取空数组的长度错误)
我知道有人对此问题提出了解决方案,有关更多详细信息,请参阅我代码的其余部分:
public class SummaryEntry implements Parcelable {
private ArrayList<Calculation> allChartValues; // NOTE: this is another nested parcel class which is basically a duplicate of Display but with float[]
private ArrayList<Display> allChartLabels;
public SummaryEntry() {
// initialize
allChartValues = new ArrayList<>();
allChartLabels = new ArrayList<>();
}
protected SummaryEntry(Parcel in) {
this();
// order in which we do this matters:
in.readTypedList(allChartLabels, Display.CREATOR);
in.readTypedList(allChartValues, Calculation.CREATOR);
}
@Override
public void writeToParcel(Parcel out, int i) {
// order in which we do this matters, must be same as reading typed lists
out.writeTypedList(allChartLabels);
out.writeTypedList(allChartValues);
}
/// ... getters and setters excluded because of irrelevance ///
/// PARCELABLE METHODS
@Override
public int describeContents() {
return 0;
}
public static final Creator<SummaryEntry> CREATOR = new Creator<SummaryEntry>() {
@Override
public SummaryEntry createFromParcel(Parcel in) {
return new SummaryEntry(in);
}
@Override
public SummaryEntry[] newArray(int size) {
return new SummaryEntry[size];
}
};
}
public class SummaryEntry实现可包裹{
private ArrayList allChartValues;//注意:这是另一个嵌套的地块类,基本上是Display的副本,但带有float[]
私有ArrayList allChartLabels;
公共摘要条目(){
//初始化
allChartValues=新的ArrayList();
allChartLabels=new ArrayList();
}
受保护的汇总条目(包裹输入){
这个();
//我们这样做的顺序很重要:
in.readTypedList(所有图表标签,Display.CREATOR);
in.readTypedList(allChartValues,Calculation.CREATOR);
}
@凌驾
公共无效写入包裹(包裹外,内部i){
//我们做这件事的顺序,必须和阅读打字列表一样
out.writeTypedList(所有图表标签);
out.writeTypedList(所有图表值);
}
///…因为不相关而被排除在外的接受者和接受者///
///可分包方法
@凌驾
公共int描述内容(){
返回0;
}
公共静态最终创建者=新创建者(){
@凌驾
公共摘要条目createFromParcel(地块中){
返回新的汇总条目(在中);
}
@凌驾
公共摘要条目[]新数组(整数大小){
返回新的SummaryEntry[大小];
}
};
}
感谢您花时间阅读这篇长篇文章。理想情况下,我正在寻找
字符串[]的解决方案
初始化问题,或者如果有人可以发布包含数组的嵌套包裹的工作代码,或者最后可能有人可以指出一种更简单的方法来实现传递这些项目,而无需嵌套两个包裹。您可以按照以下代码进行操作:
像这样使用writeArray和readArray:
尝试使用以下更新的代码:
package com.myapplication;
import android.os.Parcel;
import android.os.Parcelable;
public class User implements Parcelable {
String name;
int age;
String [] array;
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.name);
dest.writeInt(this.age);
dest.writeStringArray(this.array);
}
public User() {
}
protected User(Parcel in) {
this.name = in.readString();
this.age = in.readInt();
this.array = in.createStringArray();
}
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];
}
};
}
package com.myapplication;
导入android.os.packet;
导入android.os.Parcelable;
公共类用户实现了Parcelable{
字符串名;
智力年龄;
字符串[]数组;
@凌驾
公共int描述内容(){
返回0;
}
@凌驾
公共无效写入包裹(包裹目的地,内部标志){
目的地记录(此名称);
目的地写入(本期);
dest.writeStringArray(this.array);
}
公共用户(){
}
受保护用户(包裹中){
this.name=in.readString();
this.age=in.readInt();
this.array=in.createStringArray();
}
public static final Parcelable.Creator=新建Parcelable.Creator(){
@凌驾
公共用户createFromParcel(地块源){
返回新用户(源);
}
@凌驾
公共用户[]新数组(整数大小){
返回新用户[大小];
}
};
}
我仍然无法解决原始问题的后半部分(即如何封装阵列),但通过稍微重新设计我的程序,我成功地实现了嵌套封装实现
新的设计将实现分解为4个嵌套类,采用直接的实现。我还删除了我的数组,因为我无法在包中正确初始化它们
编辑:我也偶然发现了一个自动为你创建包裹的工具。非常有用,我希望我以前知道它!
还请注意,显然没有必要为parcelString
和Float
创建地块类。您可以调用Float.class.getClassLoader()
和String.class.getClassLoader()
为这些类使用地块生成器
这是我的密码:
包裹类别Q包含以下数组列表:
- 可包裹A类包含2个Arra
package com.myapplication; import android.os.Parcel; import android.os.Parcelable; public class User implements Parcelable { String name; int age; String [] array; @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(this.name); dest.writeInt(this.age); dest.writeStringArray(this.array); } public User() { } protected User(Parcel in) { this.name = in.readString(); this.age = in.readInt(); this.array = in.createStringArray(); } 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]; } }; }
// create the parcel Q parcel = new Q(); ArrayList<String> strings = new ArrayList<>(); ArrayList<Float> stats = new ArrayList<>(); // ... populate arraylists ... // Intent I = new Intent(CURRENTACTIVITY.this, FUTUREACTIVITY.class); // PUT THE THING I.putExtra("Data", parcel); startActivity(I);
Q parcel = getIntent().getParcelableExtra("Data"); // get data
// top level parcelable class Q public class Q implements Parcelable { private ArrayList<A> element; public Q() { this.element = new ArrayList<A>(); } public void addToA(A a) { element.add(a); } public ArrayList<A> getA() { return element; } public void setA(ArrayList<A> a) { this.element = a; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeTypedList(this.element); } private Q (Parcel in){ element = new ArrayList<A>(); in.readTypedList(this.element, A.CREATOR); } public static final Parcelable.Creator<Q> CREATOR = new Parcelable.Creator<Q>() { public Q createFromParcel(Parcel in) { return new Q(in); } public Q[] newArray(int size) { return new Q[size]; } }; } // nested parcel object A public class A implements Parcelable { private ArrayList<Float> f; private ArrayList<String> s; public A() { f = new ArrayList<>(); s = new ArrayList<>(); } public A(ArrayList<Float> f, ArrayList<String> s) { this.f = f; this.s = s; } public ArrayList<String> getS() { return s; } public void setS(ArrayList<String> s) { this.s = s; } public ArrayList<Float> getF() { return f; } public void setF(ArrayList<Float> f) { this.f = f; } protected A(Parcel in) { if (in.readByte() == 0x01) { f = new ArrayList<>(); in.readList(f, Float.class.getClassLoader()); } else { f = null; } if (in.readByte() == 0x01) { s = new ArrayList<>(); in.readList(s, String.class.getClassLoader()); } else { s = null; } } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { if (f == null) { dest.writeByte((byte) (0x00)); } else { dest.writeByte((byte) (0x01)); dest.writeList(f); } if (s == null) { dest.writeByte((byte) (0x00)); } else { dest.writeByte((byte) (0x01)); dest.writeList(s); } } @SuppressWarnings("unused") public static final Parcelable.Creator<A> CREATOR = new Parcelable.Creator<A>() { @Override public A createFromParcel(Parcel in) { return new A(in); } @Override public A[] newArray(int size) { return new A[size]; } }; }