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:
describeContents()
: This method is a content interface description and returns 0 by default.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.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>