我无法在两个活动之间传输数据

问题描述

我最近开始学习 Android 编程。我在两个活动之间传输数据时遇到问题。在第一个活动中,一些 EditText 从用户那里获取信息,并且 btn_apply 按钮应该将它们保存在一个列表中。 btn_show 按钮应该在第二个活动中显示 student_lastnames,但我的代码只重复显示最后一个 last_name。不知道是什么问题?

主要活动:

package com.example.mysixthandroidapp;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.NumberPicker;
import android.widget.TextView;

import java.io.Serializable;
import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        EditText txt_name = (EditText)findViewById(R.id.txt_name);
        EditText txt_id = (EditText)findViewById(R.id.txt_lastname);
        EditText txt_filed = (EditText)findViewById(R.id.txt_field);
        EditText txt_university = (EditText)findViewById(R.id.txt_university);
        EditText txt_startyear = (EditText)findViewById(R.id.txt_startyear);
        
        Button btn_apply = (Button)findViewById(R.id.btn_apply);
        Button btn_show = (Button)findViewById(R.id.btn_show);

        Student std = new Student();

        TextView txt_result = (TextView)findViewById(R.id.txt_result);

        final ArrayList<Student> students  = new ArrayList<Student>();
        
        btn_apply.setonClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                std.setStudent_name(txt_name.getText().toString());
                std.setStudent_lastname(txt_id.getText().toString());
                std.setStudent_field(txt_filed.getText().toString());
                std.setStudent_university(txt_university.getText().toString());
                std.setStudent_startyear(txt_startyear.getText().toString());
                students.add(std);

            }
        });


        btn_show.setonClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent myIntent = new Intent(MainActivity.this,SecondActivity.class);
                Bundle arg = new Bundle();
                arg.putSerializable("STUDENT",(Serializable)students);
                myIntent.putExtra("BUNDLE",arg);
                MainActivity.this.startActivity(myIntent);


            }
        });
    }
}

第二个活动:

package com.example.mysixthandroidapp;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;

import java.util.ArrayList;

public class SecondActivity extends AppCompatActivity {

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

        Intent intent  = getIntent();
        Bundle arg = intent.getBundleExtra("BUNDLE");
        ArrayList <Student> students_list = (ArrayList <Student>)arg.getSerializable("STUDENT");
        TextView txt_list = (TextView)findViewById(R.id.txt_list);


        for(int i = 0 ; i < students_list.size() ; i++){

            txt_list.setText("student: "+i + students_list.get(i).getStudent_lastname() + "\n");
        }

    }
}

学生班:

package com.example.mysixthandroidapp;

import java.io.Serializable;
import java.util.ArrayList;


public class Student implements java.io.Serializable {
    private String Student_name;
    private String Student_lastname;
    private String Student_field;
    private String Student_university;
    private String Student_startyear;


    public void setStudent_name(String name) {

        Student_name = name;
    }
    public void setStudent_lastname(String lname) {

        Student_lastname = lname;
    }
    public void setStudent_field(String field) {

        Student_field = field;
    }
    public void setStudent_university(String university) {

        Student_university = university;
    }
    public void setStudent_startyear(String startyear) {

        Student_startyear = startyear;
    }


    public String getStudent_name() {

        return Student_name;
    }
    public String getStudent_lastname() {

        return Student_lastname;
    }
    public String getStudent_field() {

        return Student_field;
    }
    public String getStudent_university() {

        return Student_university;
    }
    public String getStudent_startyear() {

        return Student_startyear;
    }



}

解决方法

使用 gson 将您的对象转换为 JSON 并通过意图传递它。在新的 Activity 中将 JSON 转换为对象。

在您的 build.gradle 中,将此添加到您的依赖项

implementation 'com.google.code.gson:gson:*Version*'

在您的 Activity 中,将对象转换为 json-string:

Gson gson = new Gson();
String myJson = gson.toJson(vp);
intent.putExtra("myjson",myjson);

在您的接收 Activity 中,将 json-string 转换回原始对象:

Gson gson = new Gson();
YourObject ob = gson.fromJson(getIntent().getStringExtra("myjson"),YourObject.class);

对于 Kotlin 来说完全一样

传输数据

val gson = Gson()
val intent = Intent(this,YourActivity::class.java)
intent.putExtra("identifier",gson.toJson(your_object))
startActivity(intent)

收到

val gson = Gson()
val yourObject = gson.fromJson<YourObject>(intent.getStringExtra("identifier"),YourObject::class.java)

第二种方式

  • 实现 Parcelable

    实现可序列化

    使用某种轻量级的事件总线库(例如, Greenrobot 的 EventBus 或 Square 的 Otto)

Parcelable - 速度快,符合 Android 标准,但它有很多样板代码,并且在从意图中提取值(非强类型)时需要硬编码字符串以供参考。

Serializable - 接近于零样板,但它是最慢的方法,并且在从意图(非强类型)中提取值时还需要硬编码字符串。

Event Bus - 零样板,最快的方法,不需要硬编码字符串,但它确实需要额外的依赖(虽然通常是轻量级的,~40 KB)

我发布了关于这三种方法的非常详细的比较,包括效率基准。

相关问答

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