介绍
我们经常需要在Android应用的活动之间传递数据。 一个简单的方法是使用Intent.putExtra()
,但是如果您要传递大量结构化数据,则Parcelable可能是更好的解决方案。 在这篇文章中,我将向您展示Parcelable如何使序列化类轻松地在Activity之间共享。
为什么要包裹?
Parcelable是仅Android的界面。 它允许开发人员序列化一个类,以便轻松地将其属性从一个活动转移到另一个活动。 这是通过从包裹中读取和写入对象来完成的,包裹中的对象可以包含扁平化的数据。
创建主要活动和布局
我们的主要活动将处理书籍详细信息的收集。 让我们从设置onCreate
方法开始。
package com.tutsplus.code.android.bookparcel;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//...
}
}
接下来,打开activity_main.xml来设置视图的布局和外观。 您将需要两个文本输入字段和一个提交按钮。
它看起来应该像这样:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_margin="5dp"
android:padding="5dp"
tools:context="com.tutsplus.code.android.bookparcel.MainActivity">
<EditText
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:padding="20dp"
android:textSize="15sp"
android:hint="Book Title"/>
<EditText
android:id="@+id/author"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:padding="20dp"
android:textSize="15sp"
android:hint="Book Author"/>
<Button
android:id="@+id/submit_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:text="Submit"/>
</LinearLayout>
现在打开您的主要活动,并将视图字段链接到您的活动。 您必须在onCreate()
方法中执行此操作,如下所示:
//...
final EditText mBkTitle = (EditText) findViewById(R.id.title);
final EditText mBkAuthor = (EditText) findViewById(R.id.author);
Button button = (Button) findViewById(R.id.submit_button);
要结束MainActivity
,您需要设置一个onClickListener
。 只要按下“ 提交”按钮,就会调用此方法。 发生这种情况时,将收集输入的详细信息并将其发送到下一个活动。
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Book book = new Book(mBkTitle.getText().toString(),
mBkAuthor.getText().toString());
Intent intent = new Intent(MainActivity.this, BookActivity.class);
intent.putExtra("Book", book);
startActivity(intent);
}
});
在这里,您将一个onClickListener
添加到从Activity布局中检索到的Button
实例。 只要单击“ 提交”按钮,就会运行此代码。
请注意,我们只是将Book
实例传递给putExtra()
。 稍后我们将看到,Parcelable负责将书籍数据序列化为字符串,以便可以通过Intent进行传递。
既然主要的Activity已经完成,我们需要创建BookActivity
以及Book类来保存图书信息。
创建书籍类
让我们创建一个Book
类来保存有关每本书的信息。
public class Book implements Parcelable {
// book basics
private String title;
private String author;
}
此类需要实现Parcelable
。 这将使数据从MainActivity
传递到BookActivity
。
我们还将添加一些标准的getter函数和一个构造函数,以快速创建该类的实例。
// main constructor
public Book(String title, String author) {
this.title = title;
this.author = author;
}
// getters
public String getTitle() { return title; }
public String getAuthor() { return author; }
写包裹
您可以在writeToParcel
方法中将所有类数据添加到包裹中。 这样做是为了准备转移。 该方法将传递给Parcel实例,该实例具有许多写入方法,可用于将每个字段添加到包裹中。 注意:写入数据的顺序很重要!
这是您的操作方式。
// write object values to parcel for storage
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(title);
dest.writeString(author);
}
从包裹中读取数据
就像write方法处理写入要传输的数据一样,构造函数用于从序列化的Parcel读回传输的数据。 在接收活动中将调用此方法以收集数据。
外观如下:
public Book(Parcel parcel) {
title = parcel.readString();
author = parcel.readString();
}
接收方Activity将以字符串形式获取数据,然后将调用getParcelableExtra
方法以开始收集数据的过程。 这将触发我们在上面定义的构造函数,该构造函数将反序列化数据并创建一个新的Book
实例。
Parcelable.Creator
要完成您的Parcelable类,您需要创建一个Parcelable.Creator
实例并将其分配给CREATOR
字段。 当需要对已传递给另一个组件的类的实例进行反序列化时,Parcelable API将寻找该字段。
public static final Parcelable.Creator<Book> CREATOR = new Parcelable.Creator<Book>() {
@Override
public Book createFromParcel(Parcel parcel) {
return new Book(parcel);
}
@Override
public Book[] newArray(int size) {
return new Book[0];
}
};
这将所有内容绑定在一起。 它的工作很简单,它会产生从你的Parcelable类的实例Parcel
使用所提供的地块数据。 创建者调用上面定义的构造函数,并向其传递一个Parcel
对象,然后构造函数初始化类属性。
如果您的Parcelable类将有子类,则需要使用describeContents()
方法格外小心。 这将使您标识应该由Parcelable.Creator
创建的特定子类。 您可以阅读有关Stack Overflow如何工作的更多信息 。
图书活动和布局
现在,我们可以使用“活动”一书来完成我们的应用程序。 继续并创建一个名为BookActivity
的新空活动。 使布局看起来像我下面的布局。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_margin="5dp"
android:padding="5dp"
tools:context="com.tutsplus.code.android.bookparcel.BookActivity">
<TextView
android:id="@+id/bk_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="Book"
android:textSize="30sp"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:padding="20dp"/>
<TextView
android:id="@+id/bk_author"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="Author"
android:textSize="30sp"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:padding="20dp"/>
</LinearLayout>
在activity_book.xml中 ,您仅需要两个TextView
小部件,这些小部件将用于显示书籍的标题和作者。
现在,让我们设置活动。 您的活动应该已经像这样:
package com.tutsplus.code.android.bookparcel;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class BookActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_book);
}
}
在此活动中,您希望接收从主活动传递的数据并将其显示在视图上。 因此,您将使用布局中设置的TextView
的ID检索TextView
的实例。
TextView mBkTitle = (TextView) findViewById(R.id.bk_title);
TextView mBkAuthor = (TextView) findViewById(R.id.bk_author);
然后,当然,您将调用getIntent()
因为您将在此活动中检索数据。 您将使用getParcelableExtra()
从Book类中收集要检索的数据。 接下来,将TextViews
的值设置为您收集的数据。 这是完成的过程。
Intent intent = getIntent();
Book book = intent.getParcelableExtra("Book");
mBkTitle.setText("Title:" + book.getTitle());
mBkAuthor.setText("Author:" + book.getAuthor());
构建您的应用程序并启动它,您应该会看到刚刚构建的小功能。
结论
在本文中,您已经了解了如何轻松地将对象从一个活动移动到另一个活动。 您不再需要分别检索传递给Intent对象的每个数据字段,也不必记住传递每个字段所依据的名称。 不仅如此,而且此过程比Java的序列化功能要快。
在本教程中,您学习了如何使用Parcelable将数据从一个活动传递到另一个活动。 您可以通过查看官方文档来深入了解Parcelable。