我正在尝试从一个“活动”发送客户类的对象,并在另一个“”中显示它。

客户类别的代码:

public class Customer {

    private String firstName, lastName, address;
    int age;

    public Customer(String fname, String lname, int age, String address) {

        firstName = fname;
        lastName = lname;
        age = age;
        address = address;
    }

    public String printValues() {

        String data = null;

        data = "First Name :" + firstName + " Last Name :" + lastName
        + " Age : " + age + " Address : " + address;

        return data;
    }
}

我想将其对象从一个“活动”发送到另一个“,然后在另一个活动”上显示数据。

我怎样才能做到这一点?


当前回答

我创建了一个保存临时对象的单例助手类。

public class IntentHelper {

    private static IntentHelper _instance;
    private Hashtable<String, Object> _hash;

    private IntentHelper() {
        _hash = new Hashtable<String, Object>();
    }

    private static IntentHelper getInstance() {
        if(_instance==null) {
            _instance = new IntentHelper();
        }
        return _instance;
    }

    public static void addObjectForKey(Object object, String key) {
        getInstance()._hash.put(key, object);
    }

    public static Object getObjectForKey(String key) {
        IntentHelper helper = getInstance();
        Object data = helper._hash.get(key);
        helper._hash.remove(key);
        helper = null;
        return data;
    }
}

不要将对象放在Intent中,而是使用IntentHelper:

IntentHelper.addObjectForKey(obj, "key");

在新的“活动”中,您可以获取对象:

Object obj = (Object) IntentHelper.getObjectForKey("key");

请记住,一旦加载,对象将被删除,以避免不必要的引用。

其他回答

Android活动对象可以被销毁和重建。因此,您需要使用另一种方法来查看它们或它们创建的任何对象!!!-向上的也就是说,您可以作为静态类引用传递,但对象句柄(Java调用这些“引用”,SmallTalk也是如此;但它们不是C或汇编意义上的引用)稍后可能会无效,因为Android OE的一个“特性”是任何活动都可以在稍后被销毁和重新构建。

最初的问题是“如何在Android中将对象从一个活动传递到另一个活动”,但没有人回答这个问题。当然,您可以序列化(Serializable、Parcelable、to/from JSON)并传递对象数据的副本,这样就可以创建具有相同数据的新对象;但它将不具有相同的引用/句柄。此外,许多其他人提到可以将引用存储在静态存储中。除非Android决定开启销毁您的活动,否则这将起作用。

因此,要真正解决原始问题,您需要一个静态查找,再加上每个对象将在重新创建时更新其引用。例如,如果调用其onCreate,则每个Android活动将重新列出自己。您还可以看到一些人如何使用任务列表按名称搜索“活动”。(系统正在临时销毁此活动实例以节省空间。getRunningTasks,任务列表实际上是每个活动的最新对象实例的专门列表)。

供参考:

停止:该活动被另一个活动完全遮挡(该活动现在位于“后台”)。已停止的活动也仍然活动(活动对象保留在内存中,它维护所有状态和成员信息,但未附加到窗口管理器)。但是,用户不再能看到它,当其他地方需要内存时,系统可能会将其关闭销毁“系统正在临时销毁此活动实例以节省空间。”

因此,消息总线是一个可行的解决方案。它基本上是“双关语”。而不是试图引用对象;然后重新构建设计,使用MessagePassing而不是SequentialCode。调试难度成倍增加;但它让你忽略了这些对操作环境的理解。实际上,每个对象方法访问都是反向的,因此调用者发布一条消息,而对象本身定义了该消息的处理程序。更多的代码,但可以使其在Android OE限制下更加健壮。

如果你想要的只是顶部的“活动”(由于到处都需要“上下文”,所以在Android应用程序中很常见),那么只要调用onResume,你就可以让每个“活动”在静态全局空间中将自己列为“顶部”。然后,AlertDialog或任何需要上下文的东西都可以从那里获取它。此外,使用全局有点讨厌,但可以简化到处上下传递上下文,当然,当您使用MessageBus时,IT无论如何都是全局的。

大家好,我看到了很多好的选项,但我想知道为什么没有使用绑定?

对我来说,传递对对象的引用似乎比序列化和反序列化对象更有效,但我还没有深入了解这是否是幕后发生的事情。

创建活页夹非常简单。。。

public class MyBinder extends Binder {

    private Object myObject;

    public MyBinder(Object object) {
        myObject = object;
    }

    public Object getObject() {
        return myObject;
    }

}

创造出可以使用它的parcelable并不是那么糟糕的乙醚。

public class MyParcelable implements Parcelable {

    private Object myObject;

    public MyParcelable() {
    }

    public MyParcelable(Parcel parcel) {
        myObject = ((MyBinder)parcel.readStrongBinder()).getObject();
    }

    public void setObject(Object object) {
        myObject = object;
    }

    public Object getObject() {
        return myObject;
    }

    public void writeToParcel(Parcel parcel, int flags) {
        parcel.writeStrongBinder(new MyBinder(myObject));
    }

    public int describeContents() {
        return myObject == null ? 0 : 1;
    }

    public static final Parcelable.Creator<MyParcelable> CREATOR = new Parcelable.Creator<MyParcelable>() {

        public MyParcelable createFromParcel(Parcel parcel) {
            return new MyParcelable(parcel);
        }

        public MyParcelable[] newArray(int length) {
            return new MyParcelable[length];
        }

    };
}

这个逻辑非常酷,因为实际上是在将引用从一个活动传递到另一个活动。

我建议检查空值,如果Binder的实例是MyBinder!

为了实现这一点,你。。。

把它送出去

Object myObject = "some object";
MyParcelable myParcelable = new MyParcelable();
myParcelable.setObject(myObject);

intent.putExtra("MyParcelable", myParcelable);

把它拿回来

myParcelable = (MyParcelable) getIntent().getExtras().getParcelable("MyParcelable");
myObject = myParcelable.getObject();

见鬼,有人会变得疯狂,让这个笨蛋成为真正的普通人。

一种选择是让自定义类实现Serializable接口,然后可以使用intent#putExtra()方法的putExtra变量(Serializable..)在intent extra中传递对象实例。

实际代码:

在自定义模型/对象类中:

public class YourClass implements Serializable {

在使用自定义模型/类的其他类中:

//To pass:
intent.putExtra("KEY_NAME", myObject);

myObject的类型为“YourClass”。然后,要从另一个活动中检索,请使用getSerializableExtra使用相同的Key名称获取对象。需要对YourClass进行类型转换:

// To retrieve object in second Activity
myObject = (YourClass) getIntent().getSerializableExtra("KEY_NAME");

注意:确保主自定义类的每个嵌套类都实现了Serializable接口,以避免任何序列化异常。例如:

class MainClass implements Serializable {
    
    public MainClass() {}

    public static class ChildClass implements Serializable {
         
        public ChildClass() {}
    }
}

调用活动时

Intent intent = new Intent(fromClass.this,toClass.class).putExtra("myCustomerObj",customerObj);

在toClass.java中,通过

Customer customerObjInToClass = getIntent().getExtras().getParcelable("myCustomerObj");

请确保客户类实现parcelable

public class Customer implements Parcelable {

    private String firstName, lastName, address;
    int age;

    /* all your getter and setter methods */

    public Customer(Parcel in ) {
        readFromParcel( in );
    }

    public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
        public LeadData createFromParcel(Parcel in ) {
            return new Customer( in );
        }

        public Customer[] newArray(int size) {
            return new Customer[size];
        }
    };


    @Override
    public void writeToParcel(Parcel dest, int flags) {

        dest.writeString(firstName);
        dest.writeString(lastName);
        dest.writeString(address);
        dest.writeInt(age);
    }

    private void readFromParcel(Parcel in ) {

        firstName = in .readString();
        lastName  = in .readString();
        address   = in .readString();
        age       = in .readInt();
    }

如果您选择使用Samuh描述的方式,请记住,只能发送原始值。即,可分割的值。因此,如果您的对象包含复杂对象,这些对象将不会跟随。例如,Bitmap、HashMap等变量。这些变量很难按意图传递。

一般来说,我建议您只将原始数据类型作为额外类型发送,如String、int、boolean等。在您的情况下,它将是:String fname、String lname、int age和String address。

我的观点:通过实现ContentProvider、SDCard等,可以更好地共享更复杂的对象。也可以使用静态变量,但这可能会很快导致容易出错的代码。。。

不过,这只是我的主观看法。