Освой Android играючи

Сайт Александра Климова

Шкодим

/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000

Parcelable. Передаём объекты

Усы, лапы, хвост

Очень часто программисту приходится передавать данные из одной активности в другую. Когда речь идёт о простых типах, то используется метод 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);
}

Получив объект из первой активности, мы можем извлечь необходимые данные и разложить по полочкам.

Parcelable

Если класс слишком большой, то вручную его переделывать утомительно. Существует онлайн-сервис parcelabler а также плагин для Android Studio mcharmas/android-parcelable-intellij-plugin: IntelliJ Plugin for Android Parcelable boilerplate code generation.

Дополнительное чтение

Сравнение Serializable и Parcelable.

Передаем Parcelable объекты с помощью Intent

Parcelize в Kotlin через аннотацию

Реклама