Передача кастомных элементов в bundle | Android
Как мне передать кастомный тип элементы в Bundle. Например, я хочу передать List, но не понимаю как. Почитал статьи и прочее, но после всех попыток получал только ошибки. Сейчас уже не могу сказать, какие точно. Может ли кто-то объяснить мне, как сделать это правильно?
Ответы (2 шт):
Есть несколько вариантов отправки списка List. Первый способ как и второй - заполнение списка объектами класса который вам нужен и отправка. При это класс должен быть либо parcelable либо serializable, но лучше использовать parcelable. Пример serializable класса:
public class Person implements Serializable {
private int id;
private String name;
public Hospitals(int id, String name)
{
this.id = id;
this.name = name;
}
....
}
Дальше вы из этого list делаете arraylist:
List<ClassObject> yourList = ...;
ArrayList<ClassObject> arrList = new ArrayList<>(yourList.size());
arrList.addAll(yourList);
и отправляете через bundle:
Bundle bundle = new Bundle();
bundle.putSerializable("valuesArray", arrList);
Второй вариант - конвертируем ваш объект в json и отправляем в через bundle как стринг:
String jsonList = gson.toJson(yourList);
Bundle bundle = new Bundle();
bundle.putString(...);
Но стоить помнить что у bundle есть ограничение на 1MB (пруф):
The Binder transaction buffer has a limited fixed size, currently 1MB, which is shared by all transactions in progress for the process.
Поэтому третий вариант будет без использования bundle вообще. Нужно создать класс в котором будет поле вашего списка и после заполнения этого списка в активности вы должны сетить этот список в отдельный класс. После того как список теперь находится и в другом классе тоже, то значит вы можете его взять откуда угодно в том числе и с целевой активности. Для начала создаем класс-синглтон:
public class Single {
private static final Single INSTANCE = new Single();
private Single(){}
public static Single getInstance(){
return INSTANCE;
}
}
дальше создаем в нем поле вашего массива и метод чтобы взять этот массив и добавить в него данные:
List<YourObject> myList = new List()
public List<YourObject> getArray() {
return this.myList ;
}
public void addToArray(YourObject obj) {
myList.add(obj);
}
и теперь вы можете засетить данные:
Sindle.getInstance().getArray()
и взять данные:
Sindle.getInstance().myList
Вот пример работы с синглтоном. Если же вам нужно добавить сразу весь список а не по одному элементу то нужно использовать addAll(). Вот документация про List. Ну и последний вариант - использовать sharedPreference. Этот метод не совсем хорош для таких целей но задачу тоже можно выполнить:
Set<String> tasksSet = new HashSet<String>(objList);
PreferenceManager.getDefaultSharedPreferences(context)
.edit()
.putStringSet("tasks_set", tasksSet)
.commit();
и считываем его где вам нужно:
Set<String> tasksSet = PreferenceManager.getDefaultSharedPreferences(context)
.getStringSet("tasks_set", new HashSet<String>());
List<String> tasksList = new ArrayList<String>(tasksSet);
Так же в sharedPreferences можно записать стринг json (конвертировать так как я выше показывал) и взять где вам нужно. Запись:
SharedPreferences settings = context.getSharedPreferences("my_prefs", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();
editor.putString("some_key", value).apply();
и считываем где вам нужно:
SharedPreferences settings = context.getSharedPreferences("my_prefs", Context.MODE_PRIVATE);
String data = settings.getString("some_key", "defaultValue");
@Andrew забыл только указать (упомянул вскольз) про штатный вариант с Parcelable.
Между тем, это штатный (нативный для Android) вариант, который в силу своей реализации обеспечивает очень быструю передачу и без использования сериализации и связанных с этим ограничений, в частности в документации пишется, что:
Parcel is not a general-purpose serialization mechanism. This class (and the corresponding Parcelable API for placing arbitrary objects into a Parcel) is designed as a high-performance IPC transport.
То есть по сути Parcelable - это специальный протокол передачи данных между разными процессами, который опирается на низкоуровневую реализацию с использованием особенностей реализации ядра ОС Android.
Для использования этого протокола нужно своем классе реализовать интерфейс Parcelable со статическим полем CREATOR, далее уже как обычно: putParcelable()/getParcelable()
Для сравнения эффективность Parcelable vs. Serializable
