如何在Android上将对象从一个活动传递到另一个活动

kai*_*uki 726 java android object android-intent android-activity

我正在努力从一个发送我的客户类的对象Activity并在另一个中显示它Activity.

客户类的代码:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

我想将其对象从一个发送Activity到另一个,然后在另一个上显示数据Activity.

我怎样才能做到这一点?

Sam*_*muh 845

一个选项可能是让您的自定义类实现Serializable接口,然后您可以使用方法的putExtra(Serializable..)变体在intent extra中传递对象实例Intent#putExtra().

伪代码:

//To pass:
intent.putExtra("MyClass", obj);

// To retrieve object in second Activity
getIntent().getSerializableExtra("MyClass");
Run Code Online (Sandbox Code Playgroud)

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

class MainClass implements Serializable {

    public MainClass() {}

    public static class ChildClass implements Serializable {

        public ChildClass() {}
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @OD:在我的辩护中,我从未说过这是最好的选择; OP只是要求替代方案,我建议一个.不管怎么说,多谢拉. (120认同)
  • 为什么Serializable不是一个好选择?这是一个众所周知的接口,人们的类很可能已经实现了它(例如,ArrayList已经是Serializable).为什么要更改数据对象以添加额外的代码只是为了将它们从一个类传递到另一个类?这似乎是一个糟糕的设计.我可以想象在某种程度上可能会对性能产生一些影响,但我认为在99%的情况下,人们传递的是少量数据,而他们并不关心.更简单和便携有时也更好. (82认同)
  • `Parcelable`可能对速度有好处,但实现起来很复杂.如果你需要在活动之间传递8个对象怎么办?你打算让每个对象都成为"Parcelable"吗?使用`Serializable`会更有意义.当你实现`Parcelable`时,你必须在类中添加大量代码,并以非常具体的方式对字段进行排序; `Serializable`你没有.最终,我认为这取决于你传递了多少物体以及你想要做什么. (40认同)
  • @Sander:这是答案(http://stackoverflow.com/questions/2139134/how-to-send-an-object-from-one-android-activity-to-another-using-intents/2141166#2141166)错误然后?他说'Parcelable`**是专门为此目的设计的(并且比`Serializable`快得多).我很困惑. (16认同)
  • `Serializable`是标准的Java接口.您只需通过实现接口标记一个类Serializable,Java将在某些情况下自动序列化它.`Parcelable`是一个Android特定的界面,您可以自己实现序列化.它被创建为比Serializable更高效,并解决了默认Java序列化方案的一些问题 (13认同)
  • 为什么一个人只能按原样传递一个对象?什么是在其他活动中序列化然后反序列化的重点?它不像你在不同的语言或机器之间解析它?它从一个班级到另一个班级? (7认同)
  • @Slauma事实上两者都可以工作,但Parcelable最初创建用于IPC,因为使用Serializable时的开销.但是对于活动之间的简单对象转移,它并不显着,使用Parcelables所涉及的所有丰满都不值得IMO.当不鼓励使用它时,它们不会在Bundles接口中包含putSerializable方法,并且到目前为止它不被弃用.所以在我看来,当你确定你不需要IPC使用Serializable接口时,它会容易得多.避免使用大型对象图,但同样可以使用Parcelable. (5认同)
  • 那么我们怎么能传递一个String,它在技术上是一个对象,而不是任何其他对象类型?iOS通过单个变量赋值处理此功能,为什么Android有这种禁止传递数据的方法? (5认同)
  • 我只想添加一个真实世界的例子..我使用serializable在活动之间传递一个复杂的对象.创建意图需要200ms,并且在接收活动中读取它需要100 + ms,在更改为parcelable后它分别降至6ms和68ms.所以绝对值得使用parcelable来提高速度 (3认同)

Mus*_*ven 295

使用Serializable实现您的类.我们假设这是你的实体类:

import java.io.Serializable;

@SuppressWarnings("serial") //With this annotation we are going to hide compiler warnings
public class Deneme implements Serializable {

    public Deneme(double id, String name) {
        this.id = id;
        this.name = name;
    }

    public double getId() {
        return id;
    }

    public void setId(double id) {
        this.id = id;
    }

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    private double id;
    private String name;
}
Run Code Online (Sandbox Code Playgroud)

我们dene将从X活动调用的对象发送到Y活动.X活动的某个地方;

Deneme dene = new Deneme(4,"Mustafa");
Intent i = new Intent(this, Y.class);
i.putExtra("sampleObject", dene);
startActivity(i);
Run Code Online (Sandbox Code Playgroud)

在Y活动中,我们得到了对象.

Intent i = getIntent();
Deneme dene = (Deneme)i.getSerializableExtra("sampleObject");
Run Code Online (Sandbox Code Playgroud)

而已.


Soh*_*ziz 120

  • 使用全局静态变量并不是一个好的软件工程实践.
  • 将对象的字段转换为原始数据类型可能是一项繁忙的工作.
  • 使用serializable是可以的,但它在Android平台上的性能效率不高.
  • Parcelable是专为Android设计的,您应该使用它.这是一个简单的示例:在Android活动之间传递自定义对象

您可以使用此站点为您的类生成Parcelable代码.

  • 根据这个基准测试https://bitbucket.org/afrishman/androidserializationtest Serializable比Parcelable快得多.请停止分享关于Parcelable这个5岁的废话. (14认同)
  • 也许,但是人们应该真的采取"表现"与一粒盐imo.如果以实现`Parcelable`为代价,那么我宁愿让我的POJO类与Android无关并使用`Serializable`. (9认同)
  • 全局静态变量如何"不是很好的软件工程实践"?您可以制作类似单身缓存和/或数据网格的内容,然后传递ID或类似内容.当您在Java中传递引用时,无论如何,它们在某种意义上使用全局静态变量,因为它们指向同一个对象. (6认同)
  • 如果我的对象包含嵌套的Arraylist怎么办? (4认同)

Ads*_*Ads 96

在调用活动时

Intent intent = new Intent(fromClass.this,toClass.class).putExtra("myCustomerObj",customerObj);
Run Code Online (Sandbox Code Playgroud)

在toClass.java中接收活动

Customer customerObjInToClass = getIntent().getExtras().getParcelable("myCustomerObj");
Run Code Online (Sandbox Code Playgroud)

请确保客户类实现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();
    }
Run Code Online (Sandbox Code Playgroud)


小智 95

使用gson将对象转换为JSON并通过intent传递它.在新的Activity中将JSON转换为对象.

在您的build.gradle,将其添加到您的依赖项

implementation 'com.google.code.gson:gson:2.8.4'
Run Code Online (Sandbox Code Playgroud)

在您的Activity中,将对象转换为json-string:

Gson gson = new Gson();
String myJson = gson.toJson(vp);
intent.putExtra("myjson", myjson);
Run Code Online (Sandbox Code Playgroud)

在您的接收活动中,将json-string转换回原始对象:

Gson gson = new Gson();
YourObject ob = gson.fromJson(getIntent().getStringExtra("myjson"), YourObject.class);
Run Code Online (Sandbox Code Playgroud)

对于Kotlin来说,它是完全相同的

传递数据

val gson = Gson()
val intent = Intent(this, YourActivity::class.java)
intent.putExtra("identifier", gson.toJson(your_object))
startActivity(intent)
Run Code Online (Sandbox Code Playgroud)

接收数据

val gson = Gson()
val yourObject = gson.fromJson<YourObject>(intent.getStringExtra("identifier"), YourObject::class.java)
Run Code Online (Sandbox Code Playgroud)

  • 如果你可以使用一个处理它的库(gson),那么就不需要在每个对象和每个项目中实现可序列化(浪费时间).而关于矫枉过正,那里的双核和四核手机,他们甚至可以按照这个答案的想法处理一个列表. (14认同)
  • 我还建议使用gson,因为除了上面的内容,gson还可以序列化arraylists. (4认同)
  • 这很棒!在我的例子中,我使用的是一个库,对象没有实现可序列化或可分割的.所以这是我唯一的选择 (4认同)
  • 它是一种矫枉过正,gson只是json的一种字符串序列化,它更适合实现Serializable或Paracable. (3认同)
  • 这是"最好的"选择.有些类非常简单,您不需要通过实现可序列化来使其实现过于复杂 (2认同)

Ste*_*ord 85

根据我的经验,有三种主要解决方案,每种解决方案都有其缺点和优点:

  1. 实现Parcelable

  2. 实现Serializable

  3. 使用某种轻量级的事件总线库(例如,Greenrobot的EventBus或Square的Otto)

Parcelable - 快速和Android标准,但它有很多样板代码,并且需要硬编码字符串以便在将值拉出意图时进行参考(非强类型).

Serializable - 接近零样板,但它是最慢的方法,并且在将值拉出意图时需要硬编码字符串(非强类型).

事件总线 - 零样板,最快的方法,并且不需要硬编码字符串,但它确实需要额外的依赖性(尽管通常是轻量级的,~40 KB)

我发布了围绕这三种方法的非常详细的比较,包括效率基准.

  • 链接到文章已经死了.仍然可以在webarchive上找到:https://web.archive.org/web/20160917213123/http://www.stevenmarkford.com/passing-objects-between-android-activities (4认同)

MJB*_*MJB 39

您还可以将对象的数据写入临时字符串和整数,并将它们传递给活动.当然,这样就可以传输数据,但不能传输对象本身.

但是如果你只想显示它们,而不是在另一种方法或类似的东西中使用该对象,那就足够了.我这样做只是为了显示来自另一个活动中的一个对象的数据.

String fName_temp   = yourObject.getFname();
String lName_temp   = yourObject.getLname();
String age_temp     = yourObject.getAge();
String address_temp = yourObject.getAddress();

Intent i = new Intent(this, ToClass.class);
i.putExtra("fname", fName_temp);
i.putExtra("lname", lName_temp);
i.putExtra("age", age_temp);
i.putExtra("address", address_temp);

startActivity(i);
Run Code Online (Sandbox Code Playgroud)

你也可以直接传递它们而不是temp ivars,但在我看来,这种方式更清晰.此外,您可以将temp ivars设置为null,以便GarbageCollector更快地清除它们.

祝好运!

旁注:覆盖toString()而不是编写自己的print方法.

如下面的评论中所述,这是您将数据恢复到另一个活动中的方式:

String fName = getIntent().getExtras().getInt("fname");
Run Code Online (Sandbox Code Playgroud)

  • 使用以下命令重新获取数据:String fName = getIntent().getExtras().getInt("fname"); (9认同)
  • 要获取数据:`Bundle extras = getIntent().getExtras();``String val = extras.getString("fname");` (2认同)

Yes*_*ssy 39

我找到了一个简单而优雅的方法:

  • 没有可分辨
  • 没有可序列化
  • 没有静电场
  • 没有活动巴士

方法1

第一项活动的代码:

    final Object objSent = new Object();
    final Bundle bundle = new Bundle();
    bundle.putBinder("object_value", new ObjectWrapperForBinder(objSent));
    startActivity(new Intent(this, SecondActivity.class).putExtras(bundle));        
    Log.d(TAG, "original object=" + objSent);
Run Code Online (Sandbox Code Playgroud)

第二项活动的代码:

    final Object objReceived = ((ObjectWrapperForBinder)getIntent().getExtras().getBinder("object_value")).getData();
    Log.d(TAG, "received object=" + objReceived);
Run Code Online (Sandbox Code Playgroud)

你会发现objSentobjReceived拥有相同的东西hashCode,所以它们是相同的.

但是为什么我们能以这种方式传递一个java对象呢?

实际上,android binder将为java对象创建全局JNI引用,并在没有此java对象的引用时释放此全局JNI引用.binder将在Binder对象中保存此全局JNI引用.

*注意:除非两个活动在同一个进程中运行,否则此方法只能工作,否则在(ObjectWrapperForBinder)getIntent()抛出ClassCastException.getExtras().getBinder("object_value")*

class ObjectWrapperForBinder defination

public class ObjectWrapperForBinder extends Binder {

    private final Object mData;

    public ObjectWrapperForBinder(Object data) {
        mData = data;
    }

    public Object getData() {
        return mData;
    }
}
Run Code Online (Sandbox Code Playgroud)

方法2

  • 对于发件人,
    1. 使用自定义本机方法将您的java对象添加到JNI全局引用表(通过JNIEnv :: NewGlobalRef)
    2. 把返回整数(实际上,JNIEnv :: NewGlobalRef返回jobject,这是一个指针,我们可以安全地将它转换为int)到你的Intent(通过Intent :: putExtra)
  • 对于接收器
    1. 从Intent获取整数(通过Intent :: getInt)
    2. 使用自定义本机方法从JNI全局引用表中恢复您的java对象(通过JNIEnv :: NewLocalRef)
    3. 从JNI全局引用表中删除项目(通过JNIEnv :: DeleteGlobalRef),

但是方法2有一点但是严重的问题,如果接收器无法恢复java对象(例如,在恢复java对象之前发生了一些异常,或者接收器Activity根本不存在),则java对象将成为一个孤儿或内存泄漏,方法1没有这个问题,因为android binder将处理此异常

方法3

要远程调用java对象,我们将创建一个描述java对象的数据协定/接口,我们将使用aidl文件

IDataContract.aidl

package com.example.objectwrapper;
interface IDataContract {
    int func1(String arg1);
    int func2(String arg1);
}
Run Code Online (Sandbox Code Playgroud)

第一项活动的代码

    final IDataContract objSent = new IDataContract.Stub() {

        @Override
        public int func2(String arg1) throws RemoteException {
            // TODO Auto-generated method stub
            Log.d(TAG, "func2:: arg1=" + arg1);
            return 102;
        }

        @Override
        public int func1(String arg1) throws RemoteException {
            // TODO Auto-generated method stub
            Log.d(TAG, "func1:: arg1=" + arg1);
            return 101;
        }
    };
    final Bundle bundle = new Bundle();
    bundle.putBinder("object_value", objSent.asBinder());
    startActivity(new Intent(this, SecondActivity.class).putExtras(bundle));
    Log.d(TAG, "original object=" + objSent);
Run Code Online (Sandbox Code Playgroud)

第二项活动的代码:

将AndroidManifest.xml中的android:process属性更改为非空进程名称,以确保第二个活动在另一个进程中运行

    final IDataContract objReceived = IDataContract.Stub.asInterface(getIntent().getExtras().getBinder("object_value"));
    try {
        Log.d(TAG, "received object=" + objReceived + ", func1()=" + objReceived.func1("test1") + ", func2()=" + objReceived.func2("test2"));
    } catch (RemoteException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
Run Code Online (Sandbox Code Playgroud)

通过这种方式,即使它们在不同的进程中运行,我们也可以在两个活动之间传递接口,并远程调用接口方法

方法4

方法3似乎不够简单,因为我们必须实现一个aidl接口.如果你只想做简单的任务而且方法返回值是不必要的,我们可以使用android.os.Messenger

第一个活动的代码(发件人):

public class MainActivity extends Activity {
    private static final String TAG = "MainActivity";

    public static final int MSG_OP1 = 1;
    public static final int MSG_OP2 = 2;

    public static final String EXTRA_MESSENGER = "messenger";

    private final Handler mHandler = new Handler() {

        @Override
        public void handleMessage(Message msg) {
            // TODO Auto-generated method stub
            Log.e(TAG, "handleMessage:: msg=" + msg);
            switch (msg.what) {
            case MSG_OP1:

                break;
            case MSG_OP2:
                break;

            default:

                break;
            }
            super.handleMessage(msg);
        }

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

        startActivity(new Intent(this, SecondActivity.class).putExtra(EXTRA_MESSENGER, new Messenger(mHandler)));
    }
}
Run Code Online (Sandbox Code Playgroud)

第二项活动的代码(接收方):

public class SecondActivity extends Activity {

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

        final Messenger messenger = getIntent().getParcelableExtra(MainActivity.EXTRA_MESSENGER);
        try {
            messenger.send(Message.obtain(null, MainActivity.MSG_OP1, 101, 1001, "10001"));
            messenger.send(Message.obtain(null, MainActivity.MSG_OP2, 102, 1002, "10002"));
        } catch (RemoteException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
}
Run Code Online (Sandbox Code Playgroud)

所有Messenger.send都将在Handler中异步和顺序执行.

实际上,android.os.Messenger也是一个aidl接口,如果你有android源代码,你可以找到一个名为IMessenger.aidl的文件.

package android.os;

import android.os.Message;

/** @hide */
oneway interface IMessenger {
    void send(in Message msg);
}
Run Code Online (Sandbox Code Playgroud)


Rog*_*oli 25

我创建了一个包含临时对象的单例辅助类.

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

IntentHelper.addObjectForKey(obj, "key");
Run Code Online (Sandbox Code Playgroud)

在新的Activity中,您可以获取对象:

Object obj = (Object) IntentHelper.getObjectForKey("key");
Run Code Online (Sandbox Code Playgroud)

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


Nik*_*wal 23

您可以通过多种方式访问​​其他类或Activity中的变量或对象.

A.数据库

B.共享偏好.

C.对象序列化.

D.可以保存公共数据的类可以命名为Common Utilities.这取决于你.

E.通过Intents和Parcelable Interface传递数据.

这取决于您的项目需求.

A. 数据库

SQLite是一个嵌入Android的开源数据库.SQLite支持标准的关系数据库功能,如SQL语法,事务和预准备语句.

教程

B. 共享偏好

假设您要存储用户名.所以现在有两件事,一个关键用户名,价值值.

如何存储

 // Create object of SharedPreferences.
 SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);

 //Now get Editor
 SharedPreferences.Editor editor = sharedPref.edit();

 //Put your value
 editor.putString("userName", "stackoverlow");

 //Commits your edits
 editor.commit();
Run Code Online (Sandbox Code Playgroud)

使用putString(),putBoolean(),putInt(),putFloat()和putLong()可以保存所需的dtatype.

如何获取

SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
String userName = sharedPref.getString("userName", "Not Available");
Run Code Online (Sandbox Code Playgroud)

http://developer.android.com/reference/android/content/SharedPreferences.html

C. 对象序列化

如果我们想要保存对象状态以通过网络发送它,或者您也可以将它用于您的目的,则使用对象serlization.

使用Java bean并将其作为其中一个字段存储在其中,并使用getter和setter.

JavaBeans是具有属性的Java类.将属性视为私有实例变量.由于它们是私有的,因此可以通过类中的方法从类外部访问它们.更改属性值的方法称为setter方法,而检索属性值的方法称为getter方法.

public class VariableStorage implements Serializable  {

    private String inString;

    public String getInString() {
        return inString;
    }

    public void setInString(String inString) {
        this.inString = inString;
    }
}
Run Code Online (Sandbox Code Playgroud)

使用在邮件方法中设置变量

VariableStorage variableStorage = new VariableStorage();
variableStorage.setInString(inString);
Run Code Online (Sandbox Code Playgroud)

然后使用对象序列化来序列化此对象,并在其他类中反序列化此对象.

在序列化中,对象可以表示为包含对象数据的字节序列,以及有关对象类型和对象中存储的数据类型的信息.

将序列化对象写入文件后,可以从文件中读取并反序列化.也就是说,表示对象及其数据的类型信息和字节可用于在内存中重新创建对象.

如果你想要这个教程,请参考:

D. CommonUtilities

您可以自己创建一个类,它可以包含您在项目中经常需要的常用数据.

样品

public class CommonUtilities {

    public static String className = "CommonUtilities";

}
Run Code Online (Sandbox Code Playgroud)

E. 通过意图传递数据

请参阅教程Android - Parcel数据,使用Parcelable类在活动之间传递此传递数据的选项.


May*_*ama 20

创建自己的类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;
    }

}
Run Code Online (Sandbox Code Playgroud)

在你的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); 
}
Run Code Online (Sandbox Code Playgroud)

xyz activity课堂上,您需要使用以下代码:

Intent intent=getIntent();
Customer cust=(Customer)intent.getSerializableExtra("bundle");
textViewName.setText(cust.getName());
textViewCity.setText(cust.getCity());
Run Code Online (Sandbox Code Playgroud)


Ume*_*esh 15

最好的方法是在应用程序中创建一个类(称为Control),该类将包含"Customer"类型的静态变量(在您的情况下).在Activity A中初始化变量.

例如:

Control.Customer = CustomerClass;
Run Code Online (Sandbox Code Playgroud)

然后转到Activity B并从Control类中获取它.使用变量后不要忘记指定null,否则会浪费内存.

  • 将应用程序恢复到活动B时会遇到问题.由于Android可以杀死活动,因此不会保存对象. (7认同)
  • @aez因为它从设计的角度看起来很草率,如果Intent永远处于另一个过程中,它将会非常糟糕. (4认同)

Dhi*_*dya 15

public class MyClass implements Serializable{
    Here is your instance variable
}
Run Code Online (Sandbox Code Playgroud)

现在,您希望在startActivity中传递此类的对象.只需使用:

Bundle b = new Bundle();
b.putSerializable("name", myClassObject);
intent.putExtras(b);
Run Code Online (Sandbox Code Playgroud)

这可以在这里工作,因为MyClass实现Serializable.


Vid*_*nes 12

如果您选择使用Samuh描述的方式,请记住只能发送原始值.也就是说,值是可以参与的.因此,如果您的对象包含复杂对象,则不会跟随这些对象.例如,像Bitmap,HashMap等变量......这些都很难通过意图传递.

一般来说,我会建议你发送基本数据类型的演员,如String,整型,布尔等.在你的情况将是:String fname,String lname,int age,和String address.

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

但同样,这只是我的主观意见.


Beb*_*T.N 8

我使用parcelable将数据从一个活动发送到另一个活动.这是我的代码在我的项目中正常工作.

public class Channel implements Serializable, Parcelable {

    /**  */
    private static final long serialVersionUID = 4861597073026532544L;

    private String cid;
    private String uniqueID;
    private String name;
    private String logo;
    private String thumb;


    /**
     * @return The cid
     */
    public String getCid() {
        return cid;
    }

    /**
     * @param cid
     *     The cid to set
     */
    public void setCid(String cid) {
        this.cid = cid;
    }

    /**
     * @return The uniqueID
     */
    public String getUniqueID() {
        return uniqueID;
    }

    /**
     * @param uniqueID
     *     The uniqueID to set
     */
    public void setUniqueID(String uniqueID) {
        this.uniqueID = uniqueID;
    }

    /**
     * @return The name
     */
    public String getName() {
        return name;
    }

    /**
     * @param name
     *            The name to set
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * @return the logo
     */
    public String getLogo() {
        return logo;
    }

    /**
     * @param logo
     *     The logo to set
     */
    public void setLogo(String logo) {
        this.logo = logo;
    }

    /**
     * @return the thumb
     */
    public String getThumb() {
        return thumb;
    }

    /**
     * @param thumb
     *     The thumb to set
     */
    public void setThumb(String thumb) {
        this.thumb = thumb;
    }


    public Channel(Parcel in) {
        super();
        readFromParcel(in);
    }

    public static final Parcelable.Creator<Channel> CREATOR = new Parcelable.Creator<Channel>() {
        public Channel createFromParcel(Parcel in) {
            return new Channel(in);
        }

        public Channel[] newArray(int size) {

            return new Channel[size];
        }
    };

    public void readFromParcel(Parcel in) {
        String[] result = new String[5];
        in.readStringArray(result);

        this.cid = result[0];
        this.uniqueID = result[1];
        this.name = result[2];
        this.logo = result[3];
        this.thumb = result[4];
    }

    public int describeContents() {
        return 0;
    }

    public void writeToParcel(Parcel dest, int flags) {

        dest.writeStringArray(new String[] { this.cid, this.uniqueID,
                this.name, this.logo, this.thumb});
    }
}
Run Code Online (Sandbox Code Playgroud)

在activityA中使用它如下:

Bundle bundle = new Bundle();
bundle.putParcelableArrayList("channel",(ArrayList<Channel>) channels);
Intent intent = new Intent(ActivityA.this,ActivityB.class);
intent.putExtras(bundle);
startActivity(intent);
Run Code Online (Sandbox Code Playgroud)

在ActivityB中使用它来获取数据:

Bundle getBundle = this.getIntent().getExtras();
List<Channel> channelsList = getBundle.getParcelableArrayList("channel");
Run Code Online (Sandbox Code Playgroud)


小智 7

您可以尝试使用该类.限制是它不能在一个过程之外使用.

一项活动:

 final Object obj1 = new Object();
 final Intent in = new Intent();
 in.putExtra(EXTRA_TEST, new Sharable(obj1));
Run Code Online (Sandbox Code Playgroud)

其他活动:

final Sharable s = in.getExtras().getParcelable(EXTRA_TEST);
final Object obj2 = s.obj();

public final class Sharable implements Parcelable {

    private Object mObject;

    public static final Parcelable.Creator < Sharable > CREATOR = new Parcelable.Creator < Sharable > () {
        public Sharable createFromParcel(Parcel in ) {
            return new Sharable( in );
        }


        @Override
        public Sharable[] newArray(int size) {
            return new Sharable[size];
        }
    };

    public Sharable(final Object obj) {
        mObject = obj;
    }

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

    Object obj() {
        return mObject;
    }


    @Override
    public int describeContents() {
        return 0;
    }


    @Override
    public void writeToParcel(final Parcel out, int flags) {
        final long val = SystemClock.elapsedRealtime();
        out.writeLong(val);
        put(val, mObject);
    }

    private void readFromParcel(final Parcel in ) {
        final long val = in .readLong();
        mObject = get(val);
    }

    /////

    private static final HashMap < Long, Object > sSharableMap = new HashMap < Long, Object > (3);

    synchronized private static void put(long key, final Object obj) {
        sSharableMap.put(key, obj);
    }

    synchronized private static Object get(long key) {
        return sSharableMap.remove(key);
    }
}
Run Code Online (Sandbox Code Playgroud)


Aya*_*fov 6

另一个Stack Overflow问题也讨论了这个问题.请查看使用Serializable通过intent传递数据的解决方案.重点是使用Bundle存储必要数据的对象Intent.

 Bundle bundle = new Bundle();

 bundle.putSerializable(key1, value1);
 bundle.putSerializable(key2, value2);
 bundle.putSerializable(key3, value3);

 intent.putExtras(bundle);
Run Code Online (Sandbox Code Playgroud)

提取值:

 Bundle bundle = new Bundle();

 for (String key : bundle.keySet()) {
 value = bundle.getSerializable(key));
 }
Run Code Online (Sandbox Code Playgroud)

优点Serializable是它的简单.但是,Parcelable如果您需要传输大量数据,则应考虑使用方法,因为Parcelable它是专为Android设计的,并且效率更高Serializable.您可以Parcelable使用以下方法创建类

  1. 一个在线工具 - parcelabler
  2. 适用于Android Studio的插件 - Android Parcelable代码生成器


Dro*_*nja 6

从此活动启动另一个活动,并通过Bundle Object传递参数

Intent intent = new Intent(getBaseContext(), YourActivity.class);
intent.putExtra("USER_NAME", "xyz@gmail.com");
startActivity(intent);
Run Code Online (Sandbox Code Playgroud)

检索另一个活动的数据(YourActivity)

String s = getIntent().getStringExtra("USER_NAME");
Run Code Online (Sandbox Code Playgroud)

对于简单类型的数据类型,这是可以的.但是如果你想在活动之间传递复杂的数据.你需要先将它序列化.

这里我们有员工模型

class Employee{
    private String empId;
    private int age;
    print Double salary;

    getters...
    setters...
}
Run Code Online (Sandbox Code Playgroud)

您可以使用谷歌提供的Gson lib来序列化这样的复杂数据

String strEmp = new Gson().toJson(emp);
Intent intent = new Intent(getBaseContext(), YourActivity.class);
intent.putExtra("EMP", strEmp);
startActivity(intent);

Bundle bundle = getIntent().getExtras();
String empStr = bundle.getString("EMP");
            Gson gson = new Gson();
            Type type = new TypeToken<Employee>() {
            }.getType();
            Employee selectedEmp = gson.fromJson(empStr, type);
Run Code Online (Sandbox Code Playgroud)


小智 5

克里特岛类像bean类并实现Serializable接口.然后我们可以通过该intent方法传递它,例如:

intent.putExtra("class", BeanClass);
Run Code Online (Sandbox Code Playgroud)

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

BeanClass cb = intent.getSerializableExtra("class");
Run Code Online (Sandbox Code Playgroud)


Q07*_*Q07 5

像这样在自定义类中创建两个方法

public class Qabir {

    private int age;
    private String name;

    Qabir(){
    }

    Qabir(int age,String name){
        this.age=age; this.name=name;
    }   

    // method for sending object
    public String toJSON(){
        return "{age:" + age + ",name:\"" +name +"\"}";
    }

    // method for get back original object
    public void initilizeWithJSONString(String jsonString){

        JSONObject json;        
        try {
            json =new JSONObject(jsonString );
            age=json.getInt("age");
            name=json.getString("name");
        } catch (JSONException e) {
            e.printStackTrace();
        } 
    }
}
Run Code Online (Sandbox Code Playgroud)

现在你的发件人活动就是这样的

Qabir q= new Qabir(22,"KQ");    
Intent in=new Intent(this,SubActivity.class);
in.putExtra("obj", q.toJSON());
startActivity( in);
Run Code Online (Sandbox Code Playgroud)

并在你的接收器活动

Qabir q =new Qabir();
q.initilizeWithJSONString(getIntent().getStringExtra("obj"));
Run Code Online (Sandbox Code Playgroud)