Android: Serializing Parcelable simple application

1.Parcelable Introduction

Parcelable is a serialization interface provided by Android for writing data to Parcel and reading data from Parcel. As long as a class implements this interface, the objects of this class can be serialized, mainly used for IPC (inter-process communication), object transfer between Binder and Activity.

To implement the Parcelable interface, you need to implement the following methods:

  1. describeContents(): This method is a content interface description and returns 0 by default.
  2. writeToParcel(Parcel dest, int flags): This method writes the data of the class into the externally provided Parcel, that is, packages the data that needs to be passed and saves it in the Parcel container, so as to obtain the data from the Parcel container.
  3. Parcelable.Creator: This is a static interface that contains two methods for constructing instances of classes that implement Parcelable from Parcel.

The Parcelable interface is more efficient than implementing the Serializable interface and supports Intent data transfer. It should be noted that only classes that implement the Parcelable interface can be put into Parcel.

2. Simple application to transfer data across processes

Use dataBinding to simplify development

// 在 build.gradle 文件中加入
android{

    ...
    defaultConfig{
        ...
        //加入
         dataBinding.enabled true
    }

}

1. Main page activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data>

    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

        <EditText
            android:id="@+id/etName"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="4dp"
            android:ems="10"
            android:hint="姓名"
            android:inputType="text"
            android:textSize="20sp"
            app:layout_constraintBottom_toTopOf="@+id/etAge"
            app:layout_constraintEnd_toStartOf="@+id/guideline4"
            app:layout_constraintHorizontal_bias="0.0"
            app:layout_constraintStart_toStartOf="@+id/guideline2"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.059" />

        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guideline2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            app:layout_constraintGuide_percent="0.1" />

        <EditText
            android:id="@+id/etAge"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="4dp"
            android:ems="10"
            android:hint="年龄"
            android:inputType="number"
            android:textSize="20sp"
            app:layout_constraintBottom_toTopOf="@+id/etChinese"
            app:layout_constraintEnd_toEndOf="@+id/etName"
            app:layout_constraintStart_toStartOf="@+id/etName"
            app:layout_constraintTop_toBottomOf="@+id/etName"
            app:layout_constraintVertical_bias="0.182" />

        <EditText
            android:id="@+id/etMaths"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:ems="10"
            android:hint="数学"
            android:inputType="number"
            android:textSize="20sp"
            app:layout_constraintBottom_toTopOf="@+id/etEnglish"
            app:layout_constraintEnd_toEndOf="@+id/etChinese"
            app:layout_constraintStart_toStartOf="@+id/etChinese"
            app:layout_constraintTop_toBottomOf="@+id/etChinese" />

        <EditText
            android:id="@+id/etChinese"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:ems="10"
            android:hint="语文"
            android:inputType="numberSigned"
            android:textSize="20sp"
            app:layout_constraintBottom_toTopOf="@+id/etMaths"
            app:layout_constraintEnd_toEndOf="@+id/etAge"
            app:layout_constraintStart_toStartOf="@+id/etAge"
            app:layout_constraintTop_toBottomOf="@+id/etAge" />

        <EditText
            android:id="@+id/etEnglish"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:ems="10"
            android:hint="英语"
            android:inputType="number"
            android:textSize="20sp"
            app:layout_constraintBottom_toTopOf="@+id/guideline3"
            app:layout_constraintEnd_toEndOf="@+id/etMaths"
            app:layout_constraintStart_toStartOf="@+id/etMaths"
            app:layout_constraintTop_toBottomOf="@+id/etMaths" />

        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guideline3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_percent="0.6" />

        <Button
            android:id="@+id/btnSave"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="保存"
            app:layout_constraintStart_toStartOf="@+id/guideline2"
            app:layout_constraintTop_toTopOf="@+id/guideline3" />

        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guideline4"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            app:layout_constraintGuide_percent="0.7" />
    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

2. Jump page activity_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data>

    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MenuActivity">

        <EditText
            android:id="@+id/etName"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="4dp"
            android:ems="10"
            android:hint="姓名"
            android:inputType="text"
            android:textSize="20sp"
            app:layout_constraintBottom_toTopOf="@+id/etAge"
            app:layout_constraintEnd_toStartOf="@+id/guideline4"
            app:layout_constraintHorizontal_bias="0.0"
            app:layout_constraintStart_toStartOf="@+id/guideline2"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.059" />

        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guideline2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            app:layout_constraintGuide_percent="0.1" />

        <TextView
            android:id="@+id/tvGrade"
            android:layout_width="0dp"
            android:layout_height="77dp"
            android:gravity="center"
            android:hint="等级"
            android:textSize="30sp"
            android:textStyle="bold"
            app:layout_constraintBottom_toTopOf="@+id/guideline3"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.872"
            app:layout_constraintStart_toStartOf="@+id/guideline4"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.047" />

        <EditText
            android:id="@+id/etAge"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="4dp"
            android:ems="10"
            android:hint="年龄"
            android:inputType="number"
            android:textSize="20sp"
            app:layout_constraintBottom_toTopOf="@+id/etChinese"
            app:layout_constraintEnd_toEndOf="@+id/etName"
            app:layout_constraintStart_toStartOf="@+id/etName"
            app:layout_constraintTop_toBottomOf="@+id/etName"
            app:layout_constraintVertical_bias="0.182" />

        <EditText
            android:id="@+id/etMaths"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:ems="10"
            android:hint="数学"
            android:inputType="number"
            android:textSize="20sp"
            app:layout_constraintBottom_toTopOf="@+id/etEnglish"
            app:layout_constraintEnd_toEndOf="@+id/etChinese"
            app:layout_constraintStart_toStartOf="@+id/etChinese"
            app:layout_constraintTop_toBottomOf="@+id/etChinese" />

        <EditText
            android:id="@+id/etChinese"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:ems="10"
            android:hint="语文"
            android:inputType="numberSigned"
            android:textSize="20sp"
            app:layout_constraintBottom_toTopOf="@+id/etMaths"
            app:layout_constraintEnd_toEndOf="@+id/etAge"
            app:layout_constraintStart_toStartOf="@+id/etAge"
            app:layout_constraintTop_toBottomOf="@+id/etAge" />

        <EditText
            android:id="@+id/etEnglish"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:ems="10"
            android:hint="英语"
            android:inputType="number"
            android:textSize="20sp"
            app:layout_constraintBottom_toTopOf="@+id/guideline3"
            app:layout_constraintEnd_toEndOf="@+id/etMaths"
            app:layout_constraintStart_toStartOf="@+id/etMaths"
            app:layout_constraintTop_toBottomOf="@+id/etMaths" />

        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guideline3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_percent="0.6" />

        <androidx.constraintlayout.widget.Guideline
            android:id="@+id/guideline4"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            app:layout_constraintGuide_percent="0.7" />
    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

3.Score.java

package com.example.parcelabledemo;

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

/**
 * 序列化 implements Parcelable
 * 用于跨进程传递数据
 */
public class Score implements Parcelable {
    private float math;
    private float english;
    private float chinese;
    private String grade;

    public Score(float math, float english, float chinese) {
        this.math = math;
        this.english = english;
        this.chinese = chinese;
        if (math >= 90 && english >= 90 && chinese >= 90) {
            this.grade = "A";
        } else if (math >= 80 && english >= 80 && chinese >= 80) {
            this.grade = "B";
        } else {
            this.grade = "C";
        }
    }

    protected Score(Parcel in) {
        math = in.readFloat();
        english = in.readFloat();
        chinese = in.readFloat();
        grade = in.readString();
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeFloat(math);
        dest.writeFloat(english);
        dest.writeFloat(chinese);
        dest.writeString(grade);
    }

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

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

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

    public float getMath() {
        return math;
    }

    public void setMath(float math) {
        this.math = math;
    }

    public float getEnglish() {
        return english;
    }

    public void setEnglish(float english) {
        this.english = english;
    }

    public float getChinese() {
        return chinese;
    }

    public void setChinese(float chinese) {
        this.chinese = chinese;
    }

    public String getGrade() {
        return grade;
    }

    public void setGrade(String grade) {
        this.grade = grade;
    }
}

4.Student.java

package com.example.parcelabledemo;

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

/**
 * 序列化 implements Parcelable
 * 用于跨进程传递数据
 */
public class Student implements Parcelable {
    private String name;
    private int age;
    private Score score;

    public Student(String name, int age, Score score) {
        this.name = name;
        this.age = age;
        this.score = score;
    }

    protected Student(Parcel in) {
        name = in.readString();
        age = in.readInt();
        score = in.readParcelable(Score.class.getClassLoader());
    }

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

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

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

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Score getScore() {
        return score;
    }

    public void setScore(Score score) {
        this.score = score;
    }
}

5. MyApplication.java

package com.example.parcelabledemo;

import android.app.Application;

public class MyApplication extends Application {
    //整个Activity有效 设置全局属性
    // 用于测试 Application不能跨进程传递数据
    Student student;
}

6.MainActivity.java

package com.example.parcelabledemo;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;

import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;

import com.example.parcelabledemo.databinding.ActivityMainBinding;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);

        //保存数据跳转页面事件
        binding.btnSave.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                float math = Float.parseFloat(binding.etMaths.getText().toString());
                float english = Float.parseFloat(binding.etEnglish.getText().toString());
                float chinese = Float.parseFloat(binding.etChinese.getText().toString());
                Score score = new Score(math, english, chinese);

                String name = binding.etName.getText().toString();
                int age = Integer.parseInt(binding.etAge.getText().toString());
                Student student = new Student(name, age, score);
                //传递数据
//                MyApplication myApplication = (MyApplication) getApplication();
//                myApplication.student = student;

                //意图跳转页面
                Intent intent = new Intent(MainActivity.this, MenuActivity.class);
                //bundle 传递 Parcelable 数据
                Bundle bundle = new Bundle();
                bundle.putParcelable("studentData", student);
                intent.putExtra("data", bundle);
                //跳转
                startActivity(intent);
            }
        });
    }
}

7.MenuActivity.java

package com.example.parcelabledemo;

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

import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;

import com.example.parcelabledemo.databinding.ActivityMenuBinding;

public class MenuActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
//        setContentView(R.layout.activity_menu);
        ActivityMenuBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_menu);
        //获取数据
        Intent intent = getIntent();
        Bundle bundle = intent.getBundleExtra("data");
        Student student = bundle.getParcelable("studentData");

//        MyApplication myApplication = (MyApplication) getApplication();
//        Student student = myApplication.student;

        binding.etName.setText(student.getName());
        binding.etAge.setText(String.valueOf(student.getAge()));
        binding.etChinese.setText(String.valueOf(student.getScore().getChinese()));
        binding.etMaths.setText(String.valueOf(student.getScore().getMath()));
        binding.etEnglish.setText(String.valueOf(student.getScore().getEnglish()));
        binding.tvGrade.setText(student.getScore().getGrade());
    }
}

8.AndroidManifest.xml Create a new process to test data transfer

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

    <!-- 引用全局变量  android:name=".MyApplication" -->
    <application
        android:name=".MyApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.Parcelabledemo">

        <!--   android:process=":process2" 创建一个新的进程 -->
        <activity
            android:name=".MenuActivity"
            android:process=":process2"
            android:exported="false" />
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Guess you like

Origin blog.csdn.net/jiayou2020527/article/details/134953842