#java #android #object #android-intent #bundle
#java #Android #объект #android-намерение #пакет
Вопрос:
Я пытаюсь передать свой собственный пользовательский объект в bundle:
Bundle b = new Bundle();
STMessage message = (STMessage)a.getAdapter().getItem(position);
b.putObject("message",message);
Я получаю сообщение об ошибке:
The method putObject(String, Object) is undefined for the type Bundle
Ответ №1:
Один из способов — заставить ваш пользовательский объект реализовать разделяемый интерфейс и использовать Bundle.putParcelable/Bundle.getParcelable
Комментарии:
1. В документации указано, что вы не должны использовать Serializable в качестве механизма перехода к разделению. Поскольку он использует отражение, он довольно тяжелый для системы. Смотрите developer.android.com/reference/android/os/Parcel.html (ищите writeSerializable)
2. Нет проблем! Странно, что в документах не упоминается это предостережение в Bundle one.
3. Мы также можем использовать putSerializable, который помещает сериализованный объект в пакет, чтобы сделать ваш класс сериализуемым с помощью Serializable interface
Ответ №2:
Класс модели
package com.sam.bundleobjectpass;
import java.io.Serializable;
/**
* Created by Samir on 31.8.2016.
*/
public class Model implements Serializable {
private String name;
private String surName;
private int age;
public Model(String name, String surName, int age) {
this.name = name;
this.surName = surName;
this.age = age;
}
public String getName() {
return name;
}
public String getSurName() {
return surName;
}
public int getAge() {
return age;
}
}
MainActivity
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Model model = new Model("Sam", "Sami",32);
Intent i = new Intent(MainActivity.this, ReceiverActivity.class);
i.putExtra("Editing", model); // sending our object. In Kotlin is the same
startActivity(i);
}
}
ReceiverActivity
public class ReceiverActivity extends Activity {
TextView txt_name;
TextView txt_surname;
TextView txt_age;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.second);
txt_name = (TextView)findViewById(R.id.txt_name);
txt_surname = (TextView)findViewById(R.id.txt_surname);
txt_age = (TextView)findViewById(R.id.txt_age);
// receiving our object
Model model = (Model) getIntent().getSerializableExtra("Editing");
txt_name.setText(model.getName());
txt_surname.setText(model.getSurName());
txt_age.setText("" model.getAge());
}
}
// Kotlin
val model: ProgramModel? = intent.getSerializableExtra("Editing") as ProgramModel?
model?.let { // means if not null or empty
txt_act_daily_topic.text = it.title
}
Комментарии:
1. Этот вопрос касается передачи данных с использованием bundle, а не Intent.
Ответ №3:
Поскольку использование Parsable
предназначено для высокопроизводительной передачи IPC, как упоминалось в некоторых комментариях, я попробовал использовать другой подход.
В моем подходе используется библиотека GSON от Google.
Пример
public class Person{
private String name;
private int age;
// Getter and Setters omitted
}
У вас может быть метод в служебном классе, который возвращает экземпляр Gson, это делается ради чистоты кода и организации. Я буду использовать GsonBuilder, чтобы кто-нибудь мог зарегистрировать пользовательский адаптер.
public class Utils {
private static Gson gson;
public static Gson getGsonParser() {
if(null == gson) {
GsonBuilder builder = new GsonBuilder();
gson = builder.create();
}
return gson;
}
}
Момент истины!
ПОМЕСТИТЬ
Bundle args = new Bundle();
String personJsonString = Utils.getGsonParser().toJson(person);
args.putString(PERSON_KEY, personJsonString);
ПОЛУЧИТЬ
Bundle args = getArguments();
String personJsonString = args.getString(PERSON_KEY);
Person person= Utils.getGsonParser().fromJson(personJsonString, Person.class);
В настоящее время я не знаю ограничения производительности этого подхода. Но это работает просто отлично
Комментарии:
1. спаси мой день .. это замечательно
Ответ №4:
Сделайте свой пользовательский объект подлежащим разделению или сериализуемым, затем используйте putParcelable или putSerializable.
В зависимости от сложности вашего объекта тот или иной может быть проще.
Комментарии:
1. Необходимо отметить кое-что очень важное. Bundle НЕ выполняет фактическую парцелляцию или сериализацию.
Parcel
Класс выполняет. Всякий раз, когда внешняя система принимает решение (например, activity cold recreation, при soft recreation, то есть простой ротации, разбиение может вообще не выполняться).Bundle
просто кэширует сложные объекты. Однажды я предположил, что объекты сплющены , и это неверное предположение привело к неприятным утечкам и 2 дням на их поиск.
Ответ №5:
Как сказал Райан. Также, если вы хотите передать только один объект при программном уничтожении, рассмотрите возможность использования onRetainConfigurationInstance и getLastNonConfigurationInstance для передачи сериализуемого объекта. Все дерево объектов должно быть сериализуемым. Если вы передаете объект с помощью намерения, рассмотрите возможность рефакторинга объектного кода в разделяемый код позже, как только архитектура стабилизируется. Наконец, рассмотрите возможность использования полного имени класса при сохранении объекта в Bundle, как в:
inPWState= (PasswordState) getIntent().getSerializableExtra("jalcomputing.confusetext.PasswordState");
Надеюсь, это поможет.
JAL
Ответ №6:
Это сработает, если вы сделаете свой класс object сериализуемым
class your_data_class implements Serializable