如何使用意图将对象从一个Android活动发送到另一个?


849

如何使用Intent类的方法将自定义类型的对象从一个Activity传递到另一个ActivityputExtra()


@UMMA-您无需继续将问题标记为“社区Wiki”。看看这里:meta.stackexchange.com/questions/11740/...
戴夫·韦伯

1
@Paresh:您提供的链接已损坏。您能否提供替代方案?
antiplex 2012年



我找到了一个简单而优雅的方法stackoverflow.com/a/37774966/6456129
Yessy

Answers:


751

如果您只是传递对象,那么Parcelable就是为此而设计的。与使用Java的本机序列化相比,它需要付出更多的努力,但是它的速度更快(我的意思是,WAY更快)。

在文档中,有关如何实现的一个简单示例是:

// simple class that just has one member property as an example
public class MyParcelable implements Parcelable {
    private int mData;

    /* everything below here is for implementing Parcelable */

    // 99.9% of the time you can just ignore this
    @Override
    public int describeContents() {
        return 0;
    }

    // write your object's data to the passed-in Parcel
    @Override
    public void writeToParcel(Parcel out, int flags) {
        out.writeInt(mData);
    }

    // this is used to regenerate your object. All Parcelables must have a CREATOR that implements these two methods
    public static final Parcelable.Creator<MyParcelable> CREATOR = new Parcelable.Creator<MyParcelable>() {
        public MyParcelable createFromParcel(Parcel in) {
            return new MyParcelable(in);
        }

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

    // example constructor that takes a Parcel and gives you an object populated with it's values
    private MyParcelable(Parcel in) {
        mData = in.readInt();
    }
}

请注意,如果要从给定的宗地中检索多个字段,则必须按照将其放入的相同顺序(即,采用FIFO方法)进行操作。

一旦实现Parcelable了对象,就可以通过putExtra()将它们放到Intent中

Intent i = new Intent();
i.putExtra("name_of_extra", myParcelableObject);

然后,您可以使用getParcelableExtra()将它们拉出:

Intent i = getIntent();
MyParcelable myParcelableObject = (MyParcelable) i.getParcelableExtra("name_of_extra");

如果您的对象类实现了Parcelable和Serializable,则请确保将其强制转换为以下之一:

i.putExtra("parcelable_extra", (Parcelable) myParcelableObject);
i.putExtra("serializable_extra", (Serializable) myParcelableObject);

14
如果mData是对象(例如JSONObject)而不是int,将如何实现呢?
彼得·阿杰泰

301
为什么不能没有所有这些就通过对象?我们要传递一个已经在内存中的对象。
ceklock 2012年

110
@tecnotron它的应用程序位于不同的进程中,并且具有单独的内存地址空间,您不能仅向进程中的内存块发送指针(引用),并期望它在其他进程中可用。
marcinj 2012年

12
如果我无法使对象的类可序列化或可模仿,该怎么办?
阿梅尔·何塞

11
@ceklock背后的原因如下:当活动落后并随后从内存中终止时,然后当用户从“最近”菜单中打开该活动时,它必须在该活动处创建它。它必须是相同的UI。在这种情况下,对象不在内存中。但是目的是。
tasomaniac

194

您需要将您的对象序列化为某种字符串表示形式。一种可能的字符串表示形式是JSON,如果您问我,最简单的在android中从JSON序列化序列的方法之一是通过Google GSON

在这种情况下,您只需将字符串返回值从中(new Gson()).toJson(myObject);取出并检索字符串值,fromJson然后将其用于将其转换回您的对象。

但是,如果您的对象不是很复杂,则可能不值得这样做,您可以考虑传递该对象的单独值。


19
我正在猜测,因为fiXedd的答案无需使用外部库就解决了相同的问题,这是非常可取的,因此没有人应该有理由采用我提供的解决方案(当时不知道fiXedd的出色解决方案)
David Hedlund 2010年

5
我认为是正确的。此外,JSON是更适合客户端/服务器而不是线程到线程的协议。
mobibob 2010年

16
不一定是个坏主意,尤其是。因为Gson比要为要发送的所有对象实施可包裹性要简单得多。
uvesten 2011年

7
作为iam在我的应用程序中使用gson的方法,这是一种非常简单且不错的方法!
拉尔斯

16
尼斯回答,虽然完整的解决方案是String s = (new Gson().toJson(client));,然后Cli client = new Gson().fromJson(s, Cli.class);
华Iurchuk

155

您可以通过意图发送可序列化的对象

// send where details is object
ClassName details = new ClassName();
Intent i = new Intent(context, EditActivity.class);
i.putExtra("Editing", details);
startActivity(i);


//receive
ClassName model = (ClassName) getIntent().getSerializableExtra("Editing");

And 

Class ClassName implements Serializable {
} 

2
您也可以通过意图发送Parcelable对象。
Tony gil 2013年

6
“可序列化在Android上可笑得很慢。事实上,在很多情况下,Borderline没用。” 看看stackoverflow.com/questions/5550670/...
塞拉芬的

如果活动已经在运行,该怎么办呢startActivity(i); ?我的意思是,我可以使活动A调用活动B,并将数据返回给活动A吗?我感到困惑吗?
弗朗西斯科·科拉莱斯·莫拉莱斯2014年

3
如果要序列化许多对象,@ Seraphim的性能很重要,但是用户不会注意到序列化一个对象需要1毫秒还是10毫秒。如果一个额外的意图已经是Serializable但不Parcelable,这是很少值得冒这个险,使之Parcelable
凯文·克鲁姆维德

67

对于您知道将在应用程序内传递数据的情况,请使用“全局变量”(例如静态类)

Dianne Hackborn(hackbod-Google Android软件工程师)在此问题上必须说的:

对于您知道活动在同一流程中运行的情况,您可以只通过全局变量共享数据。例如,您可能有一个全局HashMap<String, WeakReference<MyInterpreterState>> 变量,当您创建一个新的MyInterpreterState时,会为其命名一个唯一的名称,并将其放入哈希映射中。要将状态发送到另一个活动,只需将唯一名称放入哈希图中,当第二个活动启动时,它可以使用接收到的名称从哈希图中检索MyInterpreterState。


25
是的,我感到很奇怪,因为我们得到了要使用的这些Intent,然后一位高级工程师告诉我们只对数据使用全局变量。但是从马口直接就可以到达那里。
理查德·勒·梅苏里尔

1
这里的弱引用会不会成为垃圾收集的受害者?
uLYsseus 2014年

1
@uLYsseus认为这就是主意,一旦您在活动中完成对它们的操作...因此,当相关活动被销毁时,它将允许其gc
Peter Ajtai 2014年

1
@RichardLeMesurier我在想同样的事情,但是后来我看了上面引用的Dianne Hackborn的Google Groups帖子,她提到,真正的全局变量唯一的问题是使用隐式意图(它可以在包外启动活动) )。正如Dianne所提到的,这是有道理的,因为这些活动很可能对您传递给它们的自定义类型的知识为零。一旦我读到它,就使我更清楚了为什么在这种情况下全球人士可能不会是一条如此糟糕的路线,我想我也愿意分享,以防其他人也感到好奇
BMB 2016年

这些意图经过了精心设计,可以将意图传递给另一台计算机。当您实际上只是想解决一个问题时,这显然不是执行任何操作的好方法。之所以这样做不好的原因是:内存使用,CPU使用,电池使用。最后,特别是在事后看来,设计意图很复杂。有人坚持认为这是一个好主意,通常是因为“谷歌这样说”。
Lassi Kinnunen '18

49

您的课程应实现Serializable或Parcelable。

public class MY_CLASS implements Serializable

完成后,您可以在putExtra上发送对象

intent.putExtra("KEY", MY_CLASS_instance);

startActivity(intent);

要获得额外费用,您只需要做

Intent intent = getIntent();
MY_CLASS class = (MY_CLASS) intent.getExtras().getSerializable("KEY");

如果您的班级实施了Parcelable使用

MY_CLASS class = (MY_CLASS) intent.getExtras().getParcelable("KEY");

希望对您有所帮助:D


6
您的班级必须实施Serializable的错误。该类可以实现Parcelable例如。
Marc Plano-Lesay

Parcelable和Serializable @Kernald有什么区别?就处理时间而言,它更慢/不是最佳实践吗?
gumuruh 2014年

虽然Serializable是标准Java接口,但Parcelable特定于Android。在性能方面,
Parcelable

35

快速需求的简短答案

1.将您的类实现为可序列化。

如果您有任何内部类,也不要忘记将它们实现为Serializable!

public class SportsData implements  Serializable
public class Sport implements  Serializable

List<Sport> clickedObj;

2.将您的对象放入Intent

 Intent intent = new Intent(SportsAct.this, SportSubAct.class);
            intent.putExtra("sport", clickedObj);
            startActivity(intent);

3.并在另一个活动类中接收您的对象

Intent intent = getIntent();
    Sport cust = (Sport) intent.getSerializableExtra("sport");

看到这个链接,stackoverflow.com
questions/2139134/…

您可以通过实现Parcelable接口来实现相同的目的。与可序列化相比,由于代码大小,可拆分接口要花费更多的时间来实现。但是它的执行速度比可序列化的更快,并且使用的资源更少。
Kwnstantinos Nikoloutsos

27

如果您的对象类实现Serializable,则无需执行其他任何操作,则可以传递可序列化的对象。
那就是我用的。


24

在您的课程中实现可序列化

public class Place implements Serializable{
        private int id;
        private String name;

        public void setId(int id) {
           this.id = id;
        }
        public int getId() {
           return id;
        }
        public String getName() {
           return name;
        }

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

然后,您可以按意图传递此对象

     Intent intent = new Intent(this, SecondAct.class);
     intent.putExtra("PLACE", Place);
     startActivity(intent);

在第二个活动中,您可以获得这样的数据

     Place place= (Place) getIntent().getSerializableExtra("PLACE");

但是,当数据变大时,此方法将很慢。


16

您可以通过几种方法访问其他类或Activity中的变量或对象。

A.数据库

B.共享首选项。

C.对象序列化。

D.可以保存公共数据的类可以命名为Common Utilities,它取决于您。

E.通过意图和可打包接口传递数据。

这取决于您的项目需求。

A. 数据库

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

教程-http: //www.vogella.com/articles/AndroidSQLite/article.html

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

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

如何取得

SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
String userName = sharedPref.getString("userName", "Not Available");

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

C. 对象序列化

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

使用Java Bean并将其存储在他的字段之一中,并为此使用getter和setter

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

public class VariableStorage implements Serializable  {

    private String inString ;

    public String getInString() {
        return inString;
    }

    public void setInString(String inString) {
        this.inString = inString;
    }


}

使用以下命令在您的邮件方法中设置变量

VariableStorage variableStorage = new VariableStorage();
variableStorage.setInString(inString);

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

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

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

如果您想要此教程,请参考此链接

http://javawithswaranga.blogspot.in/2011/08/serialization-in-java.html

获取其他类中的变量

D. 公用事业

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

样品

public class CommonUtilities {

    public static String className = "CommonUtilities";

}

E. 通过意图传递数据

请参阅本教程以了解此传递数据的选项。

http://shri.blog.kraya.co.uk/2010/04/26/android-parcel-data-to-pass-between-activities-using-parcelable-classes/


您在(E)中提到的有关通过Intent传递数据的好教程。
remrick

16

您可以使用android BUNDLE来做到这一点。

从您的班级创建一个捆绑包,例如:

public Bundle toBundle() {
    Bundle b = new Bundle();
    b.putString("SomeKey", "SomeValue");

    return b;
}

然后将这个捆绑包与INTENT一起传递。现在,您可以通过传递如下捆绑包来重新创建类对象

public CustomClass(Context _context, Bundle b) {
    context = _context;
    classMember = b.getString("SomeKey");
}

在您的Custom类中声明并使用。


1
最好直接使用Parcelable实现,恕我直言。Bundle本身实现了Parcelable,因此您仍然可以获得性能提升,同时避免了自己实现的所有麻烦。取而代之的是,您可以使用键值对来存储和检索数据,这远比仅依赖顺序更健壮。
里沙迪尼亚

对我来说,Parcelable似乎很复杂,在上面的答案中,我正在使用来自对象的类的toBundle方法,因此将对象转换为bundle,然后可以使用构造函数将bundle转换为类对象。
om252345

仅当您通过意图传递单个对象时,此解决方案才可行。
TheIT

像json一样,但我认为json重量轻。
戴维(David)

检索对象时,它是同一对象还是副本?
马库斯

15

感谢您的包裹帮助,但我发现了另一种可选解决方案

 public class getsetclass implements Serializable {
        private int dt = 10;
    //pass any object, drwabale 
        public int getDt() {
            return dt;
        }

        public void setDt(int dt) {
            this.dt = dt;
        }
    }

活动一

getsetclass d = new getsetclass ();
                d.setDt(50);
                LinkedHashMap<String, Object> obj = new LinkedHashMap<String, Object>();
                obj.put("hashmapkey", d);
            Intent inew = new Intent(SgParceLableSampelActivity.this,
                    ActivityNext.class);
            Bundle b = new Bundle();
            b.putSerializable("bundleobj", obj);
            inew.putExtras(b);
            startActivity(inew);

在活动2中获取数据

 try {  setContentView(R.layout.main);
            Bundle bn = new Bundle();
            bn = getIntent().getExtras();
            HashMap<String, Object> getobj = new HashMap<String, Object>();
            getobj = (HashMap<String, Object>) bn.getSerializable("bundleobj");
            getsetclass  d = (getsetclass) getobj.get("hashmapkey");
        } catch (Exception e) {
            Log.e("Err", e.getMessage());
        }

1
好的答案,但是可以提高您的编码标准... +1尽管可以在比赛中带来可序列化,但是Parcellables的速度要快得多
Amit

13

我使用Gson及其强大而简单的API在活动之间发送对象,

// This is the object to be sent, can be any object
public class AndroidPacket {

    public String CustomerName;

   //constructor
   public AndroidPacket(String cName){
       CustomerName = cName;
   }   
   // other fields ....


    // You can add those functions as LiveTemplate !
    public String toJson() {
        Gson gson = new Gson();
        return gson.toJson(this);
    }

    public static AndroidPacket fromJson(String json) {
        Gson gson = new Gson();
        return gson.fromJson(json, AndroidPacket.class);
    }
}

将它们添加到要发送的对象中的2个功能

用法

将对象从A发送到B

    // Convert the object to string using Gson
    AndroidPacket androidPacket = new AndroidPacket("Ahmad");
    String objAsJson = androidPacket.toJson();

    Intent intent = new Intent(A.this, B.class);
    intent.putExtra("my_obj", objAsJson);
    startActivity(intent);

在B接收

@Override
protected void onCreate(Bundle savedInstanceState) {        
    Bundle bundle = getIntent().getExtras();
    String objAsJson = bundle.getString("my_obj");
    AndroidPacket androidPacket = AndroidPacket.fromJson(objAsJson);

    // Here you can use your Object
    Log.d("Gson", androidPacket.CustomerName);
}

我几乎在每个项目中都使用它,并且没有性能问题。


谢谢,这节省了我过多的时间。
赫里斯托斯托亚诺夫

10

我也遇到同样的问题。我通过使用静态类解决了它,将所需的任何数据存储在HashMap中。最重要的是,我使用了标准Activity类的扩展,其中我重写了onCreate onDestroy方法来隐藏数据传输和数据清除。某些荒谬的设置必须更改,例如方向处理。

注释:不提供将要传递给另一个Activity的常规对象是一件麻烦事。这就像在膝盖上开枪射击自己,并希望赢得100米。“ Parcable”不是一个足够的替代。这让我发笑...我不想在我的技术免费的API上实现此接口,因为我不想引入新的Layer ...怎么可能,我们在移动编程领域还远远没有现代范式...


9

在您的第一个活动中:

intent.putExtra("myTag", yourObject);

在第二个中:

myCustomObject myObject = (myCustomObject) getIntent().getSerializableExtra("myTag");

不要忘记使您的自定义对象可序列化:

public class myCustomObject implements Serializable {
...
}

可打包比可序列化更好!避免在您的Android代码中使用Serializable!
Filipe Brito

7

另一种方法是使用Application对象(android.app.Application)。您在AndroidManifest.xml文件中将其定义为:

<application
    android:name=".MyApplication"
    ...

然后,您可以从任何活动中调用此方法并将对象保存到 Application类中。

在FirstActivity中:

MyObject myObject = new MyObject();
MyApplication app = (MyApplication) getApplication();
app.setMyObject(myObject);

在SecondActivity中,执行以下操作:

MyApplication app = (MyApplication) getApplication();
MyObject retrievedObject = app.getMyObject(myObject);

如果您的对象具有应用程序级别范围,即必须在整个应用程序中使用它们,这将很方便。Parcelable如果要显式控制对象范围或范围受到限制,则该方法仍然更好。

但是,这Intents完全避免了使用。我不知道他们是否适合您。我使用此方法的另一种方法是让int对象的标识符通过意图发送并检索对象在Maps中具有的Application对象。


1
这不是正确的处理方式,因为对象可能是可变的,如果您在应用程序的生命周期中谈论静态对象,您可能会工作,但有时我们需要使用webservice或stackoverflow.com
Muhannad A.Alhariri

Map通过将标识符用于存储和检索对象的应用程序范围,我已经成功地将其用于从Web服务生成的对象。这种方法的唯一真正的问题是,Android会在一段时间后清除内存,因此您必须检查onResume上的空值(我认为在意图中传递的对象是持久性的,但不确定)。除此之外,我认为这并不逊色。
萨德·法鲁克

这是最好的答案。它显示了不同的活动如何引用相同的数据模型。我花了很长时间才发现这一点!
马库斯

6

在您的类模型(对象)中实现Serializable,例如:

public class MensajesProveedor implements Serializable {

    private int idProveedor;


    public MensajesProveedor() {
    }

    public int getIdProveedor() {
        return idProveedor;
    }

    public void setIdProveedor(int idProveedor) {
        this.idProveedor = idProveedor;
    }


}

和你的第一个活动

MensajeProveedor mp = new MensajeProveedor();
Intent i = new Intent(getApplicationContext(), NewActivity.class);
                i.putExtra("mensajes",mp);
                startActivity(i);

还有第二个活动(NewActivity)

        MensajesProveedor  mensajes = (MensajesProveedor)getIntent().getExtras().getSerializable("mensajes");

祝好运!!


6
public class SharedBooking implements Parcelable{

    public int account_id;
    public Double betrag;
    public Double betrag_effected;
    public int taxType;
    public int tax;
    public String postingText;

    public SharedBooking() {
        account_id = 0;
        betrag = 0.0;
        betrag_effected = 0.0;
        taxType = 0;
        tax = 0;
        postingText = "";
    }

    public SharedBooking(Parcel in) {
        account_id = in.readInt();
        betrag = in.readDouble();
        betrag_effected = in.readDouble();
        taxType = in.readInt();
        tax = in.readInt();
        postingText = in.readString();
    }

    public int getAccount_id() {
        return account_id;
    }
    public void setAccount_id(int account_id) {
        this.account_id = account_id;
    }
    public Double getBetrag() {
        return betrag;
    }
    public void setBetrag(Double betrag) {
        this.betrag = betrag;
    }
    public Double getBetrag_effected() {
        return betrag_effected;
    }
    public void setBetrag_effected(Double betrag_effected) {
        this.betrag_effected = betrag_effected;
    }
    public int getTaxType() {
        return taxType;
    }
    public void setTaxType(int taxType) {
        this.taxType = taxType;
    }
    public int getTax() {
        return tax;
    }
    public void setTax(int tax) {
        this.tax = tax;
    }
    public String getPostingText() {
        return postingText;
    }
    public void setPostingText(String postingText) {
        this.postingText = postingText;
    }
    public int describeContents() {
        // TODO Auto-generated method stub
        return 0;
    }
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(account_id);
        dest.writeDouble(betrag);
        dest.writeDouble(betrag_effected);
        dest.writeInt(taxType);
        dest.writeInt(tax);
        dest.writeString(postingText);

    }

    public static final Parcelable.Creator<SharedBooking> CREATOR = new Parcelable.Creator<SharedBooking>()
    {
        public SharedBooking createFromParcel(Parcel in)
        {
            return new SharedBooking(in);
        }
        public SharedBooking[] newArray(int size)
        {
            return new SharedBooking[size];
        }
    };

}

传递数据:

Intent intent = new Intent(getApplicationContext(),YourActivity.class);
Bundle bundle = new Bundle();
i.putParcelableArrayListExtra("data", (ArrayList<? extends Parcelable>) dataList);
intent.putExtras(bundle);
startActivity(intent);

检索数据:

Bundle bundle = getIntent().getExtras();
dataList2 = getIntent().getExtras().getParcelableArrayList("data");

5

我找到的最简单的解决方案是..创建一个带有带有getters setter的静态数据成员的类。

从一个活动中设置并从另一个活动中获取该对象。

活动A

mytestclass.staticfunctionSet("","",""..etc.);

活动b

mytestclass obj= mytestclass.staticfunctionGet();

1
或creata可序列化的类传递给另一个活动,无论您要传递什么。
UMAR

9
只要记住不要放大的脂肪物体。该对象的生存期将与应用程序的生存期相同。而且永远不会存储视图。此方法还保证内存泄漏。
里诺

1
这个答案很有用,但在内存和资源优化方面不是更好的解决方案
Atul Bhardwaj 2012年

1
通过引入全局变量,这打破了OOP原则。您永远不会知道它们处于哪种状态,无论它们是已设置还是未设置,它们都被许多线程使用,因此您必须应对这种复杂性。通常这是一个很好的内存泄漏,因为您甚至都不知道何时释放这些变量。更不用说它在应用程序的不同模块之间引入了硬性直接耦合。
2014年

2
WTF?其他两个答案要好得多。
IcyFlame

4

您可以使用putExtra(Serializable ..)和getSerializableExtra()方法来传递和检索您的类类型的对象;您将必须标记您的类可序列化,并确保所有成员变量也可序列化...


4

创建Android应用程序

文件>>新建>> Android应用程序

输入项目名称:android-pass-object-to-activity

包:com.hmkcode.android

保留其他默认设置,转到下一步,直到完成

在开始创建App之前,我们需要创建POJO类“ Person”,我们将使用该类将对象从一个活动发送到另一个活动。注意,该类正在实现Serializable接口。

人.java

package com.hmkcode.android;
import java.io.Serializable;

public class Person implements Serializable{

    private static final long serialVersionUID = 1L;

    private String name;
    private int age;

        // getters & setters....

    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + "]";
    }   
}

两种活动的两种布局

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >

<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">
    <TextView
        android:id="@+id/tvName"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:gravity="center_horizontal"
        android:text="Name" />

    <EditText
        android:id="@+id/etName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"

        android:ems="10" >
        <requestFocus />
    </EditText>
</LinearLayout>

<LinearLayout
     android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">
<TextView
    android:id="@+id/tvAge"
    android:layout_width="100dp"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:gravity="center_horizontal"
    android:text="Age" />
<EditText
    android:id="@+id/etAge"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:ems="10" />
</LinearLayout>

<Button
    android:id="@+id/btnPassObject"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"
    android:text="Pass Object to Another Activity" />

</LinearLayout>

activity_another.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
 >

<TextView
    android:id="@+id/tvPerson"
    android:layout_height="wrap_content"
    android:layout_width="fill_parent"
    android:layout_gravity="center"
    android:gravity="center_horizontal"
 />

</LinearLayout>

两种活动课程

1)ActivityMain.java

package com.hmkcode.android;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;

public class MainActivity extends Activity implements OnClickListener {

Button btnPassObject;
EditText etName, etAge;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    btnPassObject = (Button) findViewById(R.id.btnPassObject);
    etName = (EditText) findViewById(R.id.etName);
    etAge = (EditText) findViewById(R.id.etAge);

    btnPassObject.setOnClickListener(this);
}

@Override
public void onClick(View view) {

    // 1. create an intent pass class name or intnet action name 
    Intent intent = new Intent("com.hmkcode.android.ANOTHER_ACTIVITY");

    // 2. create person object
    Person person = new Person();
    person.setName(etName.getText().toString());
    person.setAge(Integer.parseInt(etAge.getText().toString()));

    // 3. put person in intent data
    intent.putExtra("person", person);

    // 4. start the activity
    startActivity(intent);
}

}

2)AnotherActivity.java

package com.hmkcode.android;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;

public class AnotherActivity extends Activity {

TextView tvPerson;

@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_another);

    // 1. get passed intent 
    Intent intent = getIntent();

    // 2. get person object from intent
    Person person = (Person) intent.getSerializableExtra("person");

    // 3. get reference to person textView 
    tvPerson = (TextView) findViewById(R.id.tvPerson);

    // 4. display name & age on textView 
    tvPerson.setText(person.toString());

}
}

4

使用谷歌的Gson库,您可以将对象传递给另一个活动。实际上,我们将以json字符串的形式转换对象,并在传递给其他活动后再次将其转换为这样的对象

考虑这样的bean类

 public class Example {
    private int id;
    private String name;

    public Example(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

我们需要传递Example类的对象

Example exampleObject=new Example(1,"hello");
String jsonString = new Gson().toJson(exampleObject);
Intent nextIntent=new Intent(this,NextActivity.class);
nextIntent.putExtra("example",jsonString );
startActivity(nextIntent);

为了阅读,我们需要在NextActivity中执行相反的操作

 Example defObject=new Example(-1,null);
    //default value to return when example is not available
    String defValue= new Gson().toJson(defObject);
    String jsonString=getIntent().getExtras().getString("example",defValue);
    //passed example object
    Example exampleObject=new Gson().fromJson(jsonString,Example .class);

在gradle中添加此依赖项

compile 'com.google.code.gson:gson:2.6.2'


3

我知道这很晚了,但是它很简单,您要做的就是让您的类实现Serializable

public class MyClass implements Serializable{

}

那么你可以传递一个意图

Intent intent=......
MyClass obje=new MyClass();
intent.putExtra("someStringHere",obje);

为了得到它,你简单地打电话

MyClass objec=(MyClass)intent.getExtra("theString");

2

如果您仍然有一个单例类(fx服务)充当模型层的网关,则可以通过在该类中具有一个带有getter和setter的变量来解决。

在活动1中:

Intent intent = new Intent(getApplicationContext(), Activity2.class);
service.setSavedOrder(order);
startActivity(intent);

在活动2中:

private Service service;
private Order order;

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

    service = Service.getInstance();
    order = service.getSavedOrder();
    service.setSavedOrder(null) //If you don't want to save it for the entire session of the app.
}

服务中:

private static Service instance;

private Service()
{
    //Constructor content
}

public static Service getInstance()
{
    if(instance == null)
    {
        instance = new Service();
    }
    return instance;
}
private Order savedOrder;

public Order getSavedOrder()
{
    return savedOrder;
}

public void setSavedOrder(Order order)
{
    this.savedOrder = order;
}

该解决方案不需要对所讨论对象进行任何序列化或其他“打包”操作。但这只会在您无论如何都使用这种架构的情况下才是有益的。


这种方法的缺点是什么?看起来很合逻辑又苗条。我总是读到你不应该这样做,但是我从来没有很好地解释可能出问题的地方。
马库斯

由于我不能再编辑评论了:这不是获取对象引用而不是副本的唯一可行解决方案吗?我需要检索相同的对象而不是副本!
马库斯

我认为这有点令人沮丧,因为它会导致高耦合。但是,是的,据我所知,如果您需要实际的对象,这种方法是最可行的。与编程一样,您可以做任何您想做的事情,您只需要仔细做。这个解决方案对我来说很有效,因为无论如何我都使用该架构,所以我更喜欢它。
Kitalda '16

实际上,我最终扩展了Application类,并将数据模型存储在那里。在Intent中,我仅中继了可用于从Application类检索原始对象的数据对象的ID。如果扩展了的应用程序类通过标准侦听器概念进行了更改,则还会通知所有使用该数据模型的对象。我知道这只适合我需要在整个应用程序中共享数据模型的情况,但对于那种情况,它是完美的,也不需要静态类和字段!
Markus

2

到目前为止,恕我直言,最简单的方式来打包对象。您只需在要使其可拆分的对象上方添加注释标签。

库中的一个示例位于https://github.com/johncarl81/parceler

@Parcel
public class Example {
    String name;
    int age;

    public Example(){ /*Required empty bean constructor*/ }

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

    public String getName() { return name; }

    public int getAge() { return age; }
}

2

首先在您的课程中实现 Parcelable。然后像这样传递对象。

SendActivity.java

ObjectA obj = new ObjectA();

// Set values etc.

Intent i = new Intent(this, MyActivity.class);
i.putExtra("com.package.ObjectA", obj);

startActivity(i);

ReceiveActivity.java

Bundle b = getIntent().getExtras();
ObjectA obj = b.getParcelable("com.package.ObjectA");

包字符串不是必需的,只是两个活动中的字符串都必须相同

参考


2

通过Bundle Object从此活动传递参数开始另一个活动

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

检索另一个活动(YourActivity)

String s = getIntent().getStringExtra("USER_NAME");

对于简单种类的数据类型来说可以。但是,如果您想在两次活动之间传递复杂的数据,则需要先对其进行序列化。

这里有员工模型

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

    getters...
    setters...
}

您可以使用Google提供的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);

2

在科特丁

在您的build.gradle中添加kotlin扩展名。

apply plugin: 'kotlin-android-extensions'

android {
    androidExtensions {
        experimental = true
   }
}

然后像这样创建您的数据类。

@Parcelize
data class Sample(val id: Int, val name: String) : Parcelable

意图传递对象

val sample = Sample(1,"naveen")

val intent = Intent(context, YourActivity::class.java)
    intent.putExtra("id", sample)
    startActivity(intent)

意图获取对象

val sample = intent.getParcelableExtra("id")

还在实验吗?
ShadeToD


1

最简单的方法是在项目为字符串的情况下使用以下代码:

intent.putextra("selected_item",item)

接收:

String name = data.getStringExtra("selected_item");

3
其仅用于字符串,整数等,但是我想要对象并使用静态对象是唯一可能的。
UMAR 2010年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.