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

客户类别的代码:

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

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

我怎样才能做到这一点?


当前回答

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

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

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

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

其他回答

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

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

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

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

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

创建自己的类Customer,如下所示:

import import java.io.Serializable;
public class Customer implements Serializable
{
    private String name;
    private String city;

    public Customer()
    {
        
    }
    public Customer(String name, String city)
    {
        this.name= name;
        this.city=city;
    }
    public String getName() 
    {
        return name;
    }
    public void setName(String name) 
    {
        this.name = name;
    }
    public String getCity() 
    {
        return city;
    }
    public void setCity(String city) 
    {
        this.city= city;
    }
    
}

在onCreate()方法中

@Override
protected void onCreate(Bundle savedInstanceState) 
{
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_top);
    
    Customer cust=new Customer();
    cust.setName("abc");
    cust.setCity("xyz");
    
    Intent intent=new Intent(abc.this,xyz.class);
    intent.putExtra("bundle",cust);
    startActivity(intent); 
}

在xyz活动类中,您需要使用以下代码:

Intent intent=getIntent();
Customer cust=(Customer)intent.getSerializableExtra("bundle");
textViewName.setText(cust.getName());
textViewCity.setText(cust.getCity());

不可能序列化任何类型的对象。例如,不能序列化携带代码而不是数据的委托方法或接口。因此,我编写了一个“Box”类,您可以使用它来传递任何类型的数据,而无需序列化。

1-将数据用于预期用途:

Intent I = new Intent(this, YourActivity.class);
CustomClass Date = new CustomClass();
Box.Add(I, "Name", Data);

2-用于从意向检索数据:

CustomClass Data = Box.Get(getIntent(), "Name");

3-要在使用后删除数据,请将此方法添加到活动中:

@Override
protected void onDestroy() {
    Box.Remove(getIntent());
    super.onDestroy();
}

4-并将此代码添加到项目中:

package ir.namirasoft.Utility;

import android.content.Intent;

import java.util.HashMap;
import java.util.Vector;

public class Box {
    // Number
    private static int Number = 1;

    public static int NextNumber() {
        return Number++;
    }

    //
    private static String _Intent_Identifier = "_Intent_Identifier";
    private static HashMap<Integer, Vector<Integer>> DeleteList = new HashMap<Integer, Vector<Integer>>();
    private static HashMap<Integer, HashMap<String, Object>> ObjectList = new HashMap<Integer, HashMap<String, Object>>();

    public static int GetIntent_Identifier(Intent I) {
        int Intent_Identifier = I.getIntExtra(_Intent_Identifier, 0);
        if (Intent_Identifier == 0)
            I.putExtra(_Intent_Identifier, Intent_Identifier = NextNumber());
        return Intent_Identifier;
    }

    public static void Add(Intent I, String Name, Object O) {
        int Intent_Identifier = GetIntent_Identifier(I);
        synchronized (ObjectList) {
            if (!ObjectList.containsKey(Intent_Identifier))
                ObjectList.put(Intent_Identifier, new HashMap<String, Object>());
            ObjectList.get(Intent_Identifier).put(Name, O);
        }
    }

    public static <T> T Get(Intent I, String Name) {
        int Intent_Identifier = GetIntent_Identifier(I);
        synchronized (DeleteList) {
            DeleteList.remove(Intent_Identifier);
        }
        return (T) ObjectList.get(Intent_Identifier).get(Name);
    }

    public static void Remove(final Intent I) {
        final int Intent_Identifier = GetIntent_Identifier(I);
        final int ThreadID = NextNumber();
        synchronized (DeleteList) {
            if (!DeleteList.containsKey(Intent_Identifier))
                DeleteList.put(Intent_Identifier, new Vector<Integer>());
            DeleteList.get(Intent_Identifier).add(ThreadID);
        }
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(60 * 1000);
                } catch (InterruptedException e) {
                }
                synchronized (DeleteList) {
                    if (DeleteList.containsKey(Intent_Identifier))
                        if (DeleteList.get(Intent_Identifier).contains(ThreadID))
                            synchronized (ObjectList) {
                                ObjectList.remove(Intent_Identifier);
                            }
                }
            }
        }).start();
    }
}

**Box类是线程安全的。

创建类似bean类的类并实现Serializable接口。然后我们可以通过intent方法传递它,例如:

intent.putExtra("class", BeanClass);

然后从其他活动中获取,例如:

BeanClass cb = intent.getSerializableExtra("class");

我一直想知道为什么这不能像调用其他活动的方法一样简单。我最近写了一个实用程序库,使它几乎如此简单。你可以在这里查看(https://github.com/noxiouswinter/gnlib_android/wiki/gnlauncher).

GNLauncher使从另一个“活动”等向“活动”发送对象/数据变得简单,就像调用该“活动”中的一个函数并将所需数据作为参数一样。它引入了类型安全性,并消除了所有必须串行化、使用字符串键附加到意图以及在另一端撤消的麻烦。

用法

使用要在要启动的“活动”上调用的方法定义接口。

public interface IPayload {
    public void sayHello(String name, int age);
}

在要启动的“活动”上实现上述界面。当活动准备就绪时,也通知GNLauncher。

public class Activity_1 extends Activity implements IPayload {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //Notify GNLauncher when the Activity is ready. 
        GNLauncher.get().ping(this);
    }

    @Override
    public void sayHello(String name, int age) {
        Log.d("gnlib_test", "Hello " + name + "! \nYour age is: " + age);
    }
}

在另一个“活动”中,获取上述“活动”的代理,并使用所需参数调用任何方法。

public class Activity_2 extends Activity {
    public void onClick(View v) {
        ((IPayload)GNLauncher.get().getProxy(this, IPayload.class, Activity_1.class)).sayHello(name, age);
    }
}

将启动第一个活动,并使用所需参数调用方法。

先决条件

请参阅https://github.com/noxiouswinter/gnlib_android/wiki#prerequisites有关如何添加依赖项的信息。