Как передать пользовательский объект в Bundle?

#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