Освой Android играючи
/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000
Очень часто программисту приходится передавать данные из одной активности в другую. Когда речь идёт о простых типах, то используется метод intent.putExtra() и ему подобные. Данный способ годится для типов String, int, long или массивов. А вот объекты таким образом передать не получится.
В Java существует специальный интерфейс Serializable, но он оказался слишком неповоротлив для мобильных устройств и пользоваться им настоятельно не рекомендуется. Для передачи объектов следует использовать другой интерфейс Parcelable.
В интерфейсе Parcelable используются два метода describeContents() и writeToParcel():
@Override
public int describeContents() {
}
@Override
public void writeToParcel(Parcel dest, int flags) {
}
Метод describeContents() описывает различного рода специальные объекты, описывающие интерфейс.
Метод writeToParcel() упаковывает объект для передачи.
Также необходимо реализовать статическое поле Parcelable.Creator<T> CREATOR, которое генерирует объект класса-передатчика.
Напишем пример. Попробуем передать объект "Мои документы". Как известно, признаком настоящего документа являются Усы, лапы, хвост (я ещё добавил бы имя). Создадим новый класс DocumentInfo, который реализует интерфейс Parcelable:
package ru.alexanderklimov.parcelable;
import android.os.Parcel;
import android.os.Parcelable;
public class DocumentInfo implements Parcelable {
private String mName; // имя кота
private String mWhiskers; // усы
private String mPaws; // лапы
private String mTail; // хвост
public DocumentInfo(String name, String whiskers, String paws, String tail) {
mName = name;
mWhiskers = whiskers;
mPaws = paws;
mTail = tail;
}
public DocumentInfo(Parcel in) {
String[] data = new String[4];
in.readStringArray(data);
mName = data[0];
mWhiskers = data[1];
mPaws = data[2];
mTail = data[3];
}
public void setCatName(String name) {
mName = name;
}
public String getCatName() {
return mName;
}
public void setWhiskers(String whiskers) {
mWhiskers = whiskers;
}
public String getWhiskers() {
return mWhiskers;
}
public String getPaws() {
return mPaws;
}
public String getTail() {
return mTail;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeStringArray(new String[] { mName, mWhiskers, mPaws, mTail });
}
public static final Parcelable.Creator<DocumentInfo> CREATOR = new Parcelable.Creator<DocumentInfo>() {
@Override
public DocumentInfo createFromParcel(Parcel source) {
return new DocumentInfo(source);
}
@Override
public DocumentInfo[] newArray(int size) {
return new DocumentInfo[size];
}
};
}
Теперь мы может передать объект через Intent. Создадим две активности. В первой активности напишем код для отправки объекта:
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
intent.putExtra("DocumentInfo", new DocumentInfo("Матроскин", "Длинные", "Белые", "Пушистый"));
startActivity(intent);
}
Вторая активность должна принять данные от первой активности:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
TextView tvName = (TextView) findViewById(R.id.textView1);
TextView tvWhiskers = (TextView) findViewById(R.id.textView2);
TextView tvPaws = (TextView) findViewById(R.id.textView3);
TextView tvTail = (TextView) findViewById(R.id.textView4);
String name = "";
String whiskers = "";
String paws = "";
String tail = "";
DocumentInfo documentInfo = (DocumentInfo)getIntent().getParcelableExtra("DocumentInfo");
name = documentInfo.getCatName();
whiskers = documentInfo.getWhiskers();
paws = documentInfo.getPaws();
tail = documentInfo.getTail();
tvName.setText("Имя кота: " + name);
tvWhiskers.setText("Усы: " + whiskers);
tvPaws.setText("Лапы: " + paws);
tvTail.setText("Хвост: " + tail);
}
Получив объект из первой активности, мы можем извлечь необходимые данные и разложить по полочкам.
Если класс слишком большой, то вручную его переделывать утомительно. Существует онлайн-сервис parcelabler а также плагин для Android Studio mcharmas/android-parcelable-intellij-plugin: IntelliJ Plugin for Android Parcelable boilerplate code generation.
Сравнение Serializable и Parcelable.