Передача даних між Activity. Серіалізація
Для передачі даних між двома Activity використовується об'єкт Intent. Через його метод putExtra() можна додати ключ і пов'язане з ним значення.
Наприклад, передача з поточної Activity в SecondActivity рядка "Hello World" з ключем "hello":
// створення об'єкта Intent для запуску SecondActivity
Intent intent = new Intent(this, SecondActivity.class);
// передача об'єкта з ключем "hello" та значенням "Hello World"
intent.putExtra("hello", "Hello World");
// запуск SecondActivity
startActivity(intent);
Для передачі даних застосовується метод putExtra(), який дозволяє передавати дані простих типів: String, int, float, double, long, short, byte, char, масиви цих типів, або об'єкти інтерфейсу Serializable.
Отримання даних в SecondActivity
Щоб отримати відправлені дані під час завантаження SecondActivity, можна скористатися методом get(), в який передається ключ об'єкта:
Bundle arguments = getIntent().getExtras();
String name = arguments.get("hello").toString(); // Hello World
Залежно від типу відправлених даних, при їх отриманні можна використовувати ряд методів об'єкта Bundle. Всі вони як параметр приймають ключ об'єкта. Основні з них:
- get(): універсальний метод, який повертає значення типу Object. Відповідно, для отриманого значення необхідно виконати перетворення до потрібного типу.
- getString(): повертає об'єкт типу String.
- getInt(): повертає значення типу int.
- getByte(): повертає значення типу byte.
- getChar(): повертає значення типу char.
- getShort(): повертає значення типу short.
- getLong(): повертає значення типу long.
- getFloat(): повертає значення типу float.
- getDouble(): повертає значення типу double.
- getBoolean(): повертає значення типу boolean.
- getCharArray(): повертає масив об'єктів типу char.
- getIntArray(): повертає масив об'єктів типу int.
- getFloatArray(): повертає масив об'єктів типу float.
- getSerializable(): повертає об'єкт інтерфейсу Serializable.
Нехай у нашому проекті будуть визначені дві Activity: MainActivity і SecondActivity.
У SecondActivity визначимо отримання даних:
package com.example.viewapp;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
public class SecondActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView textView = new TextView(this);
textView.setTextSize(26);
textView.setPadding(16, 16, 16, 16);
Bundle arguments = getIntent().getExtras();
if(arguments != null) {
String name = arguments.get("name").toString();
String company = arguments.getString("company");
int age = arguments.getInt("age");
textView.setText("Name: " + name + "\nCompany: " + company +
"\nAge: " + age);
}
setContentView(textView);
}
}
У цьому прикладі в SecondActivity ми отримуємо всі дані з об'єкта Bundle та виводимо їх у текстове поле TextView. Передбачається, що в цю Activity будуть передані три елементи: дві строки з ключами name і company, а також число з ключем age.
Тепер визначимо передачу даних у SecondActivity. Наприклад, для MainActivity у файлі activity_main.xml створимо інтерфейс з полями для введення даних:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/nameLabel"
android:layout_width="0dp"
android:layout_height="20dp"
android:text="Name:"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<EditText
android:id="@+id/name"
android:layout_width="0dp"
android:layout_height="40dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/nameLabel"/>
<TextView
android:id="@+id/companyLabel"
android:layout_width="0dp"
android:layout_height="20dp"
android:text="Company:"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/name"/>
<EditText
android:id="@+id/company"
android:layout_width="0dp"
android:layout_height="40dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/companyLabel" />
<TextView
android:id="@+id/ageLabel"
android:layout_width="0dp"
android:layout_height="20dp"
android:text="Age:"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/company"/>
<EditText
android:id="@+id/age"
android:layout_width="0dp"
android:layout_height="40dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/ageLabel"/>
<Button
android:id="@+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onClick"
android:text="Save"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toBottomOf="@+id/age"/>
</androidx.constraintlayout.widget.ConstraintLayout>
Тут визначено три текстові поля для введення даних і кнопка для відправки.
Тепер, коли користувач заповнить поля у MainActivity, ми можемо передати введені дані у SecondActivity, використовуючи Intent. Для цього в обробнику кнопки у MainActivity додаємо код:
public void onClick(View view) {
EditText nameEditText = findViewById(R.id.name);
EditText companyEditText = findViewById(R.id.company);
EditText ageEditText = findViewById(R.id.age);
String name = nameEditText.getText().toString();
String company = companyEditText.getText().toString();
int age = Integer.parseInt(ageEditText.getText().toString());
Intent intent = new Intent(this, SecondActivity.class);
intent.putExtra("name", name);
intent.putExtra("company", company);
intent.putExtra("age", age);
startActivity(intent);
}
Тепер при натисканні на кнопку дані з MainActivity будуть передані у SecondActivity.
У класі MainActivity визначаємо наступне вміст:
package com.example.viewapp;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void onClick(View v) {
EditText nameText = findViewById(R.id.name);
EditText companyText = findViewById(R.id.company);
EditText ageText = findViewById(R.id.age);
String name = nameText.getText().toString();
String company = companyText.getText().toString();
int age = Integer.parseInt(ageText.getText().toString());
Intent intent = new Intent(this, SecondActivity.class);
intent.putExtra("name", name);
intent.putExtra("company", company);
intent.putExtra("age", age);
startActivity(intent);
}
}
В обробнику натискання кнопки ми отримуємо введені в текстові поля EditText дані та передаємо їх в об'єкт Intent за допомогою методу putExtra(). Потім запускаємо SecondActivity.
У підсумку, при натисканні на кнопку, буде запущена SecondActivity, яка отримає деякі введені дані з текстових полів.

Передача складних об'єктів
У наведеному вище прикладі передавались прості дані — числа, рядки. Але також ми можемо передавати більш складні дані. Для цього використовується механізм серіалізації. Для цього натискаємо правою кнопкою миші на папку пакета, де знаходяться класи MainActivity та SecondActivity, і в контекстному меню вибираємо New -> Java Class:

Назвемо новий клас User - нехай він представлятиме користувача.

Передача складних об'єктів
Нехай клас User має наступний код:
package com.example.viewapp;
import java.io.Serializable;
public class User implements Serializable {
private String name;
private String company;
private int age;
public User(String name, String company, int age){
this.name = name;
this.company = company;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCompany() {
return company;
}
public void setCompany(String company) {
this.company = company;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
Зверніть увагу, що цей клас реалізує інтерфейс Serializable. Тепер змінюємо код MainActivity:
package com.example.viewapp;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void onClick(View v) {
EditText nameText = findViewById(R.id.name);
EditText companyText = findViewById(R.id.company);
EditText ageText = findViewById(R.id.age);
String name = nameText.getText().toString();
String company = companyText.getText().toString();
int age = Integer.parseInt(ageText.getText().toString());
User user = new User(name, company, age);
Intent intent = new Intent(this, SecondActivity.class);
intent.putExtra(User.class.getSimpleName(), user);
startActivity(intent);
}
}
Тепер замість трьох окремих даних передається один об'єкт User. У якості ключа використовується результат методу User.class.getSimpleName(), який фактично повертає назву класу.
І змінюємо клас SecondActivity:
package com.example.viewapp;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
public class SecondActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_second);
TextView textView = new TextView(this);
textView.setTextSize(26);
textView.setPadding(16, 16, 16, 16);
Bundle arguments = getIntent().getExtras();
User user;
if(arguments != null){
user = (User) arguments.getSerializable(User.class.getSimpleName());
textView.setText("Name: " + user.getName() + "\nCompany: " + user.getCompany() +
"\nAge: " + String.valueOf(user.getAge()));
}
setContentView(textView);
}
}
Для отримання даних застосовується метод getSerializable(), оскільки клас User реалізує інтерфейс Serializable. Таким чином, ми можемо передавати один об'єкт замість набору окремих даних.