Parcelable

Последнее обновление: 12.12.2020

Возможность сериализации объектов предоставляется напрямую инфраструктурой языка Java. Однако Android также предоставляет интерфейс Parcelable, который по сути также позволяет сериализовать объекты, как и Serializable, но является более оптимизированным для Android. И подобные объекты Parcelable также можно передавать между двумя activity или использовать каким-то иным образом.

Например, в прошлой теме данные передавались между activity в виде объектов User, которые использовали сериализацию. Теперь пусть класс User применяет интерфейс Parcelable:

package com.example.viewapp;

import android.os.Parcel;
import android.os.Parcelable;

public class User implements Parcelable {

    private String name;
    private String company;
    private int age;

    public static final Creator<User> CREATOR = new Creator<User>() {
        @Override
        public User createFromParcel(Parcel source) {
            String name = source.readString();
            String company = source.readString();
            int age = source.readInt();
            return new User(name, company, age);
        }

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

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

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

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(name);
        dest.writeString(company);
        dest.writeInt(age);
    }
}

Интерфейс android.os.Parcelable предполагает реализацию двух методов: describeContents() и writeToParcel(). Первый метод описывает контент и возвращает некторое числовое значение. Второй метод пишет в объект Parcel содержимое объекта User.

Для записи данных объекта в Parcel используется ряд методов, каждый из которых предназначен для определенного типа данных. Основные методы:

  • writeString()

  • writeInt()

  • writeFloat()

  • writeDouble()

  • writeByte()

  • writeLong()

  • writeIntArray()

  • writeValue() (записывает объект типа Object)

  • writeParcelable() (записывает объект типа Parcelable)

Кроме того, объект Parcelable должен содержать статическое поле CREATOR, которое представляет объект Creator<User>. Причем этот объект реализует два метода. Они нужны для создания их ранее сериализованных данных исходных объектов типа User.

Так, метод newArray() создает массив объект User.

Метод createFromParcel создает из Parcel новый объект типа User. То есть этот метод противоположен по действию методу writeToParcel. Для получения данных из Parcel применяются методы типа readString(), readInt(), readParcelable() и так далее - для чтения определенных типов данных.

Причем важно, что данные в createFromParcel считываются из объекта Parcel именно в том порядке, в котором они добавляются в этот объект в методе writeToParcel.

Допустим в activity, которая называется SecondActivity мы будем получать объект User:

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

        User user;
        if(arguments!=null){
            user = arguments.getParcelable(User.class.getSimpleName());

            textView.setText("Name: " + user.getName() + "\nCompany: " + user.getCompany() +
                    "\nAge: " + String.valueOf(user.getAge()));
        }
        setContentView(textView);
    }
}

Для получения объекта Parcelable, переданного в activity, применяется метод getParcelable(). Причем никакого приведения типов не требуется.

Для тестирования передачи Parcelable определим в файле activity_main.xml простейший интерфейс для MainActivity:

<?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:

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);
    }
}
putExtra in Android и getString in Activity in Android Java
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850