【问题标题】:How to pass custom object in Bundle?如何在Bundle中传递自定义对象?
【发布时间】:2011-04-25 23:00:53
【问题描述】:

我正在尝试将我自己的自定义对象传递到一个包中:

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

【问题讨论】:

    标签: java android object android-intent bundle


    【解决方案1】:

    由于使用 Parsable 是为高性能 IPC 传输而设计的,如某些 cmets 中所述,我尝试使用不同的方法。

    我的方法使用 google 的 GSON 库。

    例子

    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);
    

    目前我不知道这种方法的性能限制。但是效果很好

    【讨论】:

      【解决方案2】:

      一种方法是让您的自定义对象实现 Parcelable 接口并使用Bundle.putParcelable/Bundle.getParcelable

      【讨论】:

      • 文档声明你不应该使用 Serializable 作为你的首选打包机制。因为它使用反射,所以对系统来说非常沉重。见developer.android.com/reference/android/os/Parcel.html(寻找writeSerializable)
      • 我没有意识到这一点,感谢您的纠正。答案已更新。
      • 没问题!奇怪的是,文档没有在 Bundle one 中提到这个警告。
      • 我们还可以使用 putSerializable 将序列化对象放入包中,使您的类使用 Serializable 接口可序列化
      【解决方案3】:

      模型类

      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());
      
      
          }
      }
      

      // 科特林

      val model: ProgramModel? = intent.getSerializableExtra("Editing") as ProgramModel?
              model?.let { // means if not null or empty
                  txt_act_daily_topic.text = it.title
              }
      

      【讨论】:

      • 这个问题是要使用bundle传递数据,而不是Intent。
      【解决方案4】:

      使您的自定义对象为 Parcelable 或 Serializable,然后使用 putParcelable 或 putSerializable。

      根据您的对象的复杂性,一个或另一个可能更容易。

      【讨论】:

      • 必须注意一些非常重要的事情。 Bundle 不执行实际的打包或序列化。 Parcel 类可以。每当外部系统决定时(例如活动冷游戏,在简单旋转的软游戏上,可能根本不会进行打包)。 Bundle 只是缓存复杂的对象。有一次我认为这些对象是扁平化的,而这个错误的假设导致了严重的泄漏和 2 天的时间才能找到它们。
      【解决方案5】:

      正如瑞恩所说。此外,如果您只想在软杀时传递一个对象,请考虑使用 onRetainConfigurationInstance 和 getLastNonConfigurationInstance 来传递可序列化对象。整个对象树必须是可序列化的。如果您通过意图传递对象,请在架构稳定后考虑将对象代码重构为 Parceable 代码。最后,考虑在将对象存储到 Bundle 时使用类的完全限定名称,如下所示:

      inPWState= (PasswordState) getIntent().getSerializableExtra("jalcomputing.confusetext.PasswordState");
      

      希望对您有所帮助。 日航

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-12-03
        • 2013-10-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-06-22
        相关资源
        最近更新 更多