在意图Parceable、Serializable之间传输对象的 ArrayList <T> 抛出 NullPointerException

问题描述

在将通用 ArrayList 传递给另一个活动时遇到 NullPointerException,不幸的是,无法检测到原因。也许有人对这个主题有一些很好的意见。

我已经生成了 1000 个类型的对象(索引 1-1000)。 ObjectsDEGR.class 本身实现了 Serializable 和 Parceable 接口。

为了确保每个属性都被填充,我在开始时初始化了每个属性 使用 0,因为 NPE 被抛出,如果一个属性缺少一个值,那么我可以检测到这一点。

计算变量“category”不同值的循环条件,如下表所示:

我已经通过方法中的 setter 初始化了对象的属性

  • allObjektsBasicInitialisation()
  • overwriteObjects(int category)

之后,我通过 writetoArrayList(int category) 方法提取了 1000 个对象的 n=20 个元素, 它返回一个 ArrayList,具体取决于固有的优先级:

  • 返回所有 Box=1 的对象列表,如果至少有一个属性 Box=1 的对象
  • 如果没有Box=1的对象,则返回Box=2的所有对象的列表
  • 如果也没有 Box=2 的对象,则返回 Box=3 的所有对象的列表

Box 始终是 {1,2,3} 之外的值。

后来我想通过 putExtra() 将返回的 ArrayList 数据发送到另一个活动和 并使用 getIntent().getParcelableArrayListExtra 获取它们。

但是现在,仍然会抛出 NPE,确实填充了 objectsDEGR 对象的属性。 我在objectsDEGR.class 中用transient 关键字标记了一些属性,因为我以后只想用序列化在永久内存中写入非瞬态对象属性。 这就是我尝试使用界面的原因:Parceable。

我读过在包裹中写入通用数据是不可能的,所以在这种情况下传输具有接口 parceable 的通用 ArrayList 也不是有效的方法

我遗漏了方法 createrandomPlaces(int category)(它有很多代码,我需要使代码更易读/更短)。如果没有检测到原因,则故障可能在此方法内部。

我的 mainActivity 类:

public class testActivity extends AppCompatActivity implements View.OnClickListener {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_degr);

    Button button1 = (Button) findViewById(R.id.button1);
    Button button2 = (Button) findViewById(R.id.button2);
    Button button3 = (Button) findViewById(R.id.button3);

    button1.setonClickListener(this);
    button2.setonClickListener(this);
    button3.setonClickListener(this);
}

private int category;
public int getCategory() {
    return category;
}
public void setCategory(int category) {
    this.category = category;
}

int nV = 20;
public int getnV() {
    return nV;
}

int arraySIZE = 1000;

//+++++++++++ ARRAYINITIALISIERUNG ++++++++++

numbersCalculation[] randomNumbersArray = new numbersCalculation[getnV()];
ObjectsDEGR[] basicDEGR = new ObjectsDEGR[arraySIZE];

//+++++++++++++ METHODEN +++++++++++++++

private void allObjektsBasicInitialisation() {

    for (int g = 0; g < arraySIZE; g++) {

            basicDEGR[g] = new ObjectsDEGR(0,0);
            basicDEGR[g].setVoc(getResources().getIdentifier("vocgR" + g,"string",getPackageName()));
            basicDEGR[g].setVocTR(getResources().getIdentifier("vocDE" + g,getPackageName()));

            if (g==0){
            basicDEGR[g].setIndex(arraySIZE+1);}
            else {
                basicDEGR[g].setIndex(g);
            }

            basicDEGR[g].setBox(1);
    }
}

private void overwriteObjects(int category) {

    for (int r = ((category-1)*nV); r < nV+((category-1)*nV); r++) {
        basicDEGR[r].setVocR1(getResources().getIdentifier("vocgR" + randomNumbersArray[r- (category-1)*nV].getPlatz1(),getPackageName()));
        basicDEGR[r].setVocF1(getResources().getIdentifier("vocgR" + randomNumbersArray[r- (category-1)*nV].getPlatz2(),getPackageName()));
        basicDEGR[r].setVocF2(getResources().getIdentifier("vocgR" + randomNumbersArray[r- (category-1)*nV].getPlatz3(),getPackageName()));
        basicDEGR[r].setVocF3(getResources().getIdentifier("vocgR" + randomNumbersArray[r- (category-1)*nV].getPlatz4(),getPackageName()));
        basicDEGR[r].setVocF4(getResources().getIdentifier("vocgR" + randomNumbersArray[r- (category-1)*nV].getPlatz5(),getPackageName()));
        basicDEGR[r].setVocF5(getResources().getIdentifier("vocgR" + randomNumbersArray[r- (category-1)*nV].getPlatz6(),getPackageName()));
    }
}

public ArrayList<ObjectsDEGR> writetoArrayList(int category) {

    ArrayList<ObjectsDEGR> Box1Filtered = new ArrayList<>();
    ArrayList<ObjectsDEGR> Box2Filtered = new ArrayList<>();
    ArrayList<ObjectsDEGR> Box3Filtered = new ArrayList<>();

    Integer comparer1 = 1;
    Integer comparer2 = 2;
    Integer comparer3 = 3;

    //region Implementierung
    for (int j = ((category-1)*nV); j < nV+((category-1)*nV); j++){

        if (comparer1.equals(basicDEGR[j].getBox())) {
            Box1Filtered.add(basicDEGR[j]);
        }
        else if (comparer2.equals(basicDEGR[j].getBox())) {
            Box2Filtered.add(basicDEGR[j]);
        }
        else if (comparer3.equals(basicDEGR[j].getBox())) {
            Box3Filtered.add(basicDEGR[j]);
        }
        else {
            Box3Filtered.add(basicDEGR[j]);
        }
    }//endregion

    if (Box1Filtered.isEmpty())
    {
        if (Box2Filtered.isEmpty()) {
            return Box3Filtered;
        }
        else {
            return Box2Filtered;
        }
    }
    else
    {
        return Box1Filtered;
    }
}
private void createrandomPlaces(int category) {}

public void openVocDegrActivity(){
    Intent vocDEGR = new Intent (this,testVocActivity.class);

   vocDEGR.putExtra("CATEGORY",getCategory());
   vocDEGR.putExtra("NV",getnV());
   vocDEGR.putExtra("VOC_ARRAY",writetoArrayList(getCategory()));

    startActivity(vocDEGR);
}

@Override
public void onClick(View category) {

    Button button1 = (Button) findViewById(R.id.button1);
    Button button2 = (Button) findViewById(R.id.button2);
    Button button3 = (Button) findViewById(R.id.button3);

    button1.setonClickListener(this);
    button2.setonClickListener(this);
    button3.setonClickListener(this);

    allObjektsBasicInitialisation();

    switch (category.getId()) {
        case R.id.button1:
            setCategory(1);
            createrandomPlaces(getCategory());
            overwriteObjects(getCategory());
            openVocDegrActivity();
            break;

        case R.id.button2:
            setCategory(2);
            createrandomPlaces(getCategory());
            overwriteObjects(getCategory());
            openVocDegrActivity();
            break;

        case R.id.button3:
            setCategory(3);
            createrandomPlaces(getCategory());
            overwriteObjects(getCategory());
            openVocDegrActivity();
            break;
    }
}}

接收者类:

public class testVocActivity extends AppCompatActivity implements View.OnClickListener {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.voc_degr);

    //region Buttonimplementierung

    Button button1 = (Button) findViewById(R.id.button1);
    Button button2 = (Button) findViewById(R.id.button2);
    Button button3 = (Button) findViewById(R.id.button3);
    Button button4 = (Button) findViewById(R.id.button4);
    Button button5 = (Button) findViewById(R.id.button5);
    Button button6 = (Button) findViewById(R.id.button6);
    TextView tvVoc = (TextView) findViewById(R.id.tv_voc);
    Button button_weiter = (Button) findViewById(R.id.button_weiter);

    button1.setonClickListener(this);
    button2.setonClickListener(this);
    button3.setonClickListener(this);
    button4.setonClickListener(this);
    button5.setonClickListener(this);
    button6.setonClickListener(this);

    //endregion

} //end of onCreate()

// ++++++++++ INTENT informatION TRANSFER +++++++

int nV = getIntent().getIntExtra("NV",0);
int category = getIntent().getIntExtra("CATEGORY",0);

public ArrayList <ObjectsDEGR> intentGetter(){

    return getIntent().getParcelableArrayListExtra("VOC_ARRAY");
}

ArrayList <ObjectsDEGR> transferredItemsList = new ArrayList<>(intentGetter());
int numberOfEntries = intentGetter().size();

    @Override
public void onClick(View view) {

}}

对象类:

public class ObjectsDEGR implements Serializable,Parcelable {

private String voc;
private String vocTR;
private int index;
private Integer Box;

private transient String vocR1;
private transient String vocF1;
private transient String vocF2;
private transient String vocF3;
private transient String vocF4;
private transient String vocF5;

//+++++++++++ KONSTRUKTOR +++++++++++++

public ObjectsDEGR(int voc,int vocTR,int index,int Box,int vocR1,int vocF1,int vocF2,int vocF3,int vocF4,int vocF5){

    this.voc = Integer.toString(voc);
    this.vocTR = Integer.toString(vocTR);
    this.index = index;
    this.vocR1 = Integer.toString(vocR1);
    this.vocF1 = Integer.toString(vocF1);
    this.vocF2 = Integer.toString(vocF2);
    this.vocF3 = Integer.toString(vocF3);
    this.vocF4 = Integer.toString(vocF4);
    this.vocF5 = Integer.toString(vocF5);
    this.Box = Box;
}

protected ObjectsDEGR(Parcel in) {
    voc = in.readString();
    vocTR = in.readString();
    index = in.readInt();
    if (in.readByte() == 0) {
        Box = null;
    } else {
        Box = in.readInt();
    }
}

@Override
public void writetoParcel(Parcel dest,int flags) {
    dest.writeString(voc);
    dest.writeString(vocTR);
    dest.writeInt(index);
    if (Box == null) {
        dest.writeByte((byte) 0);
    } else {
        dest.writeByte((byte) 1);
        dest.writeInt(Box);
    }
}

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

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

    @Override
    public ObjectsDEGR[] newArray(int size) {
        return new ObjectsDEGR[size];
    }
};

//+++++++++ GETTER +++++++++

public int getIndex(){
    return index;
}
public String getVoc() {
    return voc;
}
public String getVocTR(){
    return vocTR;
}
public String getVocR1() {
    return vocR1;
}
public String getVocF1() {
    return vocF1;
}
public String getVocF2() {
    return vocF2;
}
public String getVocF3() {
    return vocF3;
}
public String getVocF4() {
    return vocF4;
}
public String getVocF5() {
    return vocF5;
}
public int getBox(){
    return Box;
}

//++++ SETTER +++++

public void setIndex(int index){
    this.index = index;
}
public void setVoc(int voc){
    this.voc = Integer.toString(voc);
}
public void setVocTR(int vocTR){
    this.vocTR = Integer.toString(vocTR);
}
public void setVocR1(int vocR1){
    this.vocR1 = Integer.toString(vocR1);
}
public void setVocF1(int vocF1){
    this.vocF1 = Integer.toString(vocF1);
}
public void setVocF2(int vocF2){
    this.vocF2 = Integer.toString(vocF2);
}
public void setVocF3(int vocF3){
    this.vocF3 = Integer.toString(vocF3);
}
public void setVocF4(int vocF4){
    this.vocF4 = Integer.toString(vocF4);
}
public void setVocF5(int vocF5){
    this.vocF5 = Integer.toString(vocF5);
}
public void setBox (int Box){ this.Box = Box;}}

错误日志:

E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.doriandev.ganiu,PID: 22261
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.doriandev.ganiu/com.doriandev.ganiu.voc_degr_activity}: java.lang.NullPointerException: Attempt to invoke virtual method 'int android.content.Intent.getIntExtra(java.lang.String,int)' on a null object reference
    at android.app.ActivityThread.performlaunchActivity(ActivityThread.java:3194)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
    at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
    at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
    at android.os.Handler.dispatchMessage(Handler.java:107)
    at android.os.Looper.loop(Looper.java:214)
    at android.app.ActivityThread.main(ActivityThread.java:7356)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
 Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int android.content.Intent.getIntExtra(java.lang.String,int)' on a null object reference
    at com.doriandev.ganiu.voc_degr_activity.<init>(voc_degr_activity.java:65)
    at java.lang.class.newInstance(Native Method)
    at android.app.AppComponentFactory.instantiateActivity(AppComponentFactory.java:95)
    at androidx.core.app.CoreComponentFactory.instantiateActivity(CoreComponentFactory.java:45)
    at android.app.Instrumentation.newActivity(Instrumentation.java:1243)
    at android.app.ActivityThread.performlaunchActivity(ActivityThread.java:3182)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409) 
    at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83) 
    at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) 
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016) 
    at android.os.Handler.dispatchMessage(Handler.java:107) 
    at android.os.Looper.loop(Looper.java:214) 
    at android.app.ActivityThread.main(ActivityThread.java:7356) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930) 

解决方法

好的,将功能组合在一个活动中并构建更像导航菜单(具有自己的用户界面)的中间活动可能会更好。此中间活动仅将 int 参数(类别)传递给下游活动,该参数在 onClick() 方法中用 setter 覆盖。最后,完整的对象创建和永久数据存储发生在此活动中,无需在活动之间传递全部 1000 个对象。这需要重新设计代码,但会更容易。

感谢您的投入!

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...