androidandroid-activityappcompatactivity

I can not transfer data between two activities


I start learning Android programming recently. I have a problem with transferring data between two activities. In the first activity, some EditTexts take information from the user and the btn_apply button should save them in a list. The btn_show button should show the students_lastnames on the second activity but my code only shows the last last_name repeatedly. I don't know what is the problem?

Main Activity:

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);


            }
        });
    }
}

Second Activity:

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");
        }

    }
}

Student Class:

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



}

Solution

  • Use gson to convert your object to JSON and pass it through intent. In the new Activity convert the JSON to an object.

    In your build.gradle, add this to your dependencies

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

    In your Activity, convert the object to json-string:

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

    In your receiving Activity, convert the json-string back to the original object:

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

    For Kotlin it's quite the same

    Transfer data

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

    Received by

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

    2nd Way

    Parcelable - fast and Android standard, but it has lots of boilerplate code and requires hard-coded strings for reference when pulling values out the intent (non-strongly typed).

    Serializable - close to zero boilerplate, but it is the slowest approach and also requires hard-coded strings when pulling values out the intent (non-strongly typed).

    Event Bus - zero boilerplate, fastest approach, and does not require hard-coded strings, but it does require an additional dependency (although usually lightweight, ~40 KB)

    I posted a very detailed comparison around these three approaches, including efficiency benchmarks.