2013-10-06 66 views
2

这是我第一次尝试寻求一个解决方案来解决我的问题,所以试着做一个善良的家伙!我发现了许多解决方案,我通过简单的搜索来处理这个网站的问题,但是这次我没有运气。我没有找到适合我的问题,所以我结束了一个新的问题。通过意图传递可串行化的对象

我试图通过一个目标从一个活动传递到另一个活动。我有一个抽象类和两个子类(其中一个也抽象)如下。我需要他们是抽象的。我删除了很多代码(抽象方法等),只是为了找到问题所在,并且最终得到了这些非常简单的类,而且我仍然遇到同样的问题。

public abstract class MyObject { 

    private boolean New; 
    private boolean Modified; 

    public MyObject() { 
     New = true; 
    } 

    public boolean isNew() { 
     return New; 
    } 

    protected void setNew(boolean value) { 
     New = value; 
    } 

    protected boolean isModified() { 
     return Modified; 
    } 

    protected void setModified(boolean value) { 
     Modified = value; 
    } 

} 

public abstract class MyItemBase extends MyObject { 

    private Long Id; 
    private String Description; 

    public MyItemBase() { 
     super(); 
    } 

    public Long getId() { 
     return Id; 
    } 

    public void setId(Long id) { 
     Id = id; 
    } 

    public String getDescription() { 
     return Description; 
    } 

    public void setDescription(String description) { 
     Description = description; 
    } 

} 

public class MyItem extends MyItemBase implements Serializable { 

    private static final long serialVersionUID = -2875901021692711701L; 

    public MyItem() { 
     super(); 
    } 

} 

我有两个活动,ActivityA与一个按钮来调用ActivityB如下。

public class ActivityA extends Activity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_a); 

     Button btn = (Button) findViewById(R.id.button); 
     btn.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       Intent intent = new Intent(getApplicationContext(), 
         ActivityB.class); 

       MyItem item = new MyItem(); 
       item.setId((long) 1); 
       item.setDescription("test"); 

       intent.putExtra("MyItem", (Serializable) item); 
       startActivityForResult(intent, 1); 
      } 

     }); 
    } 

} 

public class ActivityB extends Activity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_b); 

     MyItem item = (MyItem) getIntent().getSerializableExtra("MyItem"); 
     ((TextView) findViewById(R.id.text)).setText(item.getDescription()); 
    } 

} 

因此,当我从第二个活动收到MyItem并且完全没有错误时,两个属性Id和Description都为null。实际上它是一个新对象,因为New属性是正确的。现在,如果我尝试获取对象,我把准确后,在意向中的第一个活动像

intent.putExtra("MyItem", (Serializable) item); 
MyItem newItem = (MyItem) intent.getSerializableExtra("MyItem"); 
startActivityForResult(intent, 1); 

它工作正常。 newItem具有所有具有正确值的属性。

任何想法?

感谢各位!

+1

''你想传递'Object'作为'Serializable'必须实现'Serializable'接口。 – Sajmon

回答

1

the official Serializable doc

类不实现此接口不会有任何其状态的序列化或反序列化。可序列化类的所有子类本身都是可序列化的。

你的基类没有实现Serializable,所以它的字段没有被序列化。

MyItemBase(甚至MyObjectSerializable及其所有后代也将成为Serializable(没有明确地实现接口)。

+0

就是这样......我以为我应该只在“final”子类上实现Serializable。无论我在MyObject或MyItemBase上实现Serializable,它都可以正常工作。其实我从MyItem中移除了Serializable并仍然正常工作。我不明白这背后的逻辑。无论如何,我仍然困惑,为什么它在我打电话给活动B之前从意图中提取并获取对象的时候起作用。我当然接受了答案。非常感谢! – pavlospap

+0

1)那么,逻辑在规范中。在序列化对象时,它首先序列化对象类中的字段。然后,只要他们也实现了Serializable,它就会向上移动父项链并对其字段进行序列化。这可以让你拥有庞大的基类,而不会对序列化产生重大影响,只需从基类中实现Serializable即可。这是否是一个好主意是一个单独的讨论。 2)它在调用活动B之前工作,因为该对象尚未被序列化。只有当parcel被写入时(在startActivity内)才会这样做。 – Delyan

+0

P.S. Android上的序列化速度很慢(由于所有反射都在进行)。这就是为什么Android团队想出了Parcelable(这是超快的)。记住,如果你发现序列化是你的瓶颈。 – Delyan