如何使用 Intents 将对象从一个 Android Activity 发送到另一个?

Posted

技术标签:

【中文标题】如何使用 Intents 将对象从一个 Android Activity 发送到另一个?【英文标题】:How to send an object from one Android Activity to another using Intents? 【发布时间】:2011-01-09 11:53:11 【问题描述】:

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

【问题讨论】:

@UMMA - 您无需一直将您的问题标记为“社区 Wiki”。看看这里:meta.stackexchange.com/questions/11740/… @Paresh:您提供的链接已损坏。你能提供一个替代方案吗? How to pass object from one activity to another in android 的可能副本 查看这个答案。 ***.com/questions/8857546/… 我发现了一个简单优雅的方法***.com/a/37774966/6456129 【参考方案1】:

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

A.数据库

B.共享偏好。

C.对象序列化。

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

E.通过 Intents 和 Parcelable 接口传递数据。

这取决于您的项目需求。

A. 数据库

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

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

B. 共享偏好

假设您要存储用户名。所以现在会有两个东西一个Key用户名,ValueValue。

如何储存

 // Create an 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() 可以保存所需的数据类型。

如何获取

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

然后使用对象序列化来序列化这个对象,并在你的其他类中反序列化这个对象。

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

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

如果你想要这个教程参考这个链接

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

Get variable in other classes

D. CommonUtilities

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

示例

public class CommonUtilities 

    public static String className = "CommonUtilities";


E. 通过 Intent 传递数据

有关传递数据的选项,请参阅本教程。

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

【讨论】:

您在 (E) 中提到的关于通过 Intents 传递数据的好教程。【参考方案2】:

最简单的 java 方式是:在你的 pojo/model 类中实现可序列化

推荐用于Android的性能视图:make model parcelable

【讨论】:

【参考方案3】:

在你的类中实现可序列化

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 intent = new Intent(this, SecondAct.class);
     intent.putExtra("PLACE", Place);
     startActivity(intent);

在第二个活动中你可以得到这样的数据

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

但是当数据变大时,这种方法会很慢。

【讨论】:

【参考方案4】:

如果您只是传递对象,那么 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();
    

请注意,如果您要从给定 Parcel 中检索多个字段,则必须按照放入它们的相同顺序执行此操作(即采用 FIFO 方法)。

一旦你的对象实现了Parcelable,只需将它们放入你的Intents 和putExtra():

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

然后你可以用getParcelableExtra()把它们拉回来:

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

如果您的 Object Class 实现 Parcelable 和 Serializable,请确保您确实转换为以下之一:

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

【讨论】:

如果 mData 是对象(例如 JSONObject)而不是 int,这将如何实现? 为什么不能只传递没有这一切的对象?我们想要传递一个已经在内存中的对象。 @tecnotron 其因为应用程序位于不同的进程中,并且具有单独的内存地址空间,您不能只将指针(引用)发送到进程中的内存块并期望它在另一个进程中可用。 如果我不能使对象的类可序列化或可解析怎么办? @ceklock 背后的原因如下:当活动落后并后来从内存中杀死,然后当用户从最近的菜单中打开它时,它必须在它离开的地方创建活动离开。它必须是相同的用户界面。在这种情况下,对象不在内存中。但意图是。【参考方案5】:
We can send data one Activty1 to Activity2 with multiple ways like.
1- Intent
2- bundle
3- create an object and send through intent
.................................................
1 - Using intent
Pass the data through intent
Intent intentActivity1 = new Intent(Activity1.this, Activity2.class);
intentActivity1.putExtra("name", "Android");
startActivity(intentActivity1);
Get the data in Activity2 calss
Intent intent = getIntent();
if(intent.hasExtra("name"))
     String userName = getIntent().getStringExtra("name");

..................................................
2- Using Bundle
Intent intentActivity1 = new Intent(Activity1.this, Activity2.class);
Bundle bundle = new Bundle();
bundle.putExtra("name", "Android");
intentActivity1.putExtra(bundle);
startActivity(bundle);
Get the data in Activity2 calss
Intent intent = getIntent();
if(intent.hasExtra("name"))
     String userName = getIntent().getStringExtra("name");

..................................................
3-  Put your Object into Intent
Intent intentActivity1 = new Intent(Activity1.this, Activity2.class);
            intentActivity1.putExtra("myobject", myObject);
            startActivity(intentActivity1); 
 Receive object in the Activity2 Class
Intent intent = getIntent();
    Myobject obj  = (Myobject) intent.getSerializableExtra("myobject");

【讨论】:

【参考方案6】:

在科尔廷

在你的 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")

【讨论】:

还是实验性的吗?【参考方案7】:
Start another activity from this activity pass parameters via Bundle Object

Intent intent = new Intent(this, YourActivity.class);
Intent.putExtra(AppConstants.EXTRAS.MODEL, cModel);
startActivity(intent);
Retrieve on another activity (YourActivity)

ContentResultData cModel = getIntent().getParcelableExtra(AppConstants.EXTRAS.MODEL);

【讨论】:

请试试这对我有用..这里的模型是寓言。【参考方案8】:

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

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

但是,如果您的对象不是很复杂,那么开销可能不值得,您可以考虑改为传递对象的单独值。

【讨论】:

我猜是因为 fiXedd 的答案在不使用外部库的情况下解决了同样的问题,以一种更可取的方式,没有人应该有理由采用我提供的解决方案(当时不知道 fixedd 的出色解决方案) 我认为这是正确的。此外,JSON 是一种更适合客户端/服务器而不是线程到线程的协议。 不一定是个坏主意,尤其是。因为 Gson 使用起来比为您要发送的所有对象实现 parcelable 要简单得多。 因为 iam 在我的应用程序中使用 gson,这是一个非常简单和好方法! 不错的答案,虽然完整的解决方案是String s = (new Gson().toJson(client));,然后是Cli client = new Gson().fromJson(s, Cli.class);【参考方案9】:

快速需求的简短回答

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.并在另一个 Activity 类中接收您的对象

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

【讨论】:

查看此链接,***.com/questions/2139134/… 你可以通过实现 Parcelable 接口来实现同样的事情。由于代码大小,Parcelable 接口与 Serializable 相比需要更多时间来实现。但它的执行速度比 Serializable 更快,并且使用的资源更少。【参考方案10】:

我使用 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);

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

【讨论】:

谢谢,这为我节省了数小时的复杂性。【参考方案11】:

从此活动开始另一个活动,通过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);

【讨论】:

【参考方案12】:

首先在您的班级中实现 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");

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

REFERENCE

【讨论】:

【参考方案13】:

POJO类“Post”(注意是实现了Serializable)

package com.example.booklib;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import android.graphics.Bitmap;

public class Post implements Serializable
    public String message;
    public String bitmap;
    List<Comment> commentList = new ArrayList<Comment>();
    public String getMessage() 
        return message;
    
    public void setMessage(String message) 
        this.message = message;
    
    public String getBitmap() 
        return bitmap;
    
    public void setBitmap(String bitmap) 
        this.bitmap = bitmap;
    
    public List<Comment> getCommentList() 
        return commentList;
    
    public void setCommentList(List<Comment> commentList) 
        this.commentList = commentList;
    


POJO类“Comment”(既然是Post类的成员,还需要实现Serializable)

    package com.example.booklib;

    import java.io.Serializable;

    public class Comment implements Serializable
        public String message;
        public String fromName;
        public String getMessage() 
            return message;
        
        public void setMessage(String message) 
            this.message = message;
        
        public String getFromName() 
            return fromName;
        
        public void setFromName(String fromName) 
            this.fromName = fromName;
        

    

然后在您的活动类中,您可以执行以下操作将对象传递给另一个活动。

ListView listview = (ListView) findViewById(R.id.post_list);
listview.setOnItemClickListener(new OnItemClickListener()
        @Override
        public void onItemClick(AdapterView<?> parent, View view,
                int position, long id) 
            Post item = (Post)parent.getItemAtPosition(position);
            Intent intent = new Intent(MainActivity.this,CommentsActivity.class);
            intent.putExtra("post",item);
            startActivity(intent);

        
    );

在你的接收者类“CommentsActivity”你可以得到如下数据

Post post =(Post)getIntent().getSerializableExtra("post");

【讨论】:

【参考方案14】:

使用 google 的 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'

【讨论】:

【参考方案15】:

我知道这已经晚了,但它很简单。你所要做的就是让你的类实现 Serializable like

public class MyClass implements Serializable


然后你可以传递给类似的意图

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

要得到它,你只需调用

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

【讨论】:

【参考方案16】:
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");

【讨论】:

【参考方案17】:

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

下面是库中的一个示例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; 

【讨论】:

【参考方案18】:

在你的类模型(对象)中实现 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");

祝你好运!

【讨论】:

【参考方案19】:

如果您有一个单例类(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;

此解决方案不需要对相关对象进行任何序列化或其他“打包”。但只有在您使用这种架构时才会有好处。

【讨论】:

这种方法的缺点是什么?它看起来如此合乎逻辑和苗条。我一直读到你不应该那样做,但我从来没有很好地解释什么会出错。 因为我不能再编辑我的评论了:这不是获取对象引用而不是副本的唯一可能解决方案吗?我需要检索相同的对象而不是副本! 我认为这有点令人沮丧,因为它会导致高耦合。但是,是的,据我所知,如果您需要实际对象,这种方法是最可行的。在编程中,你可以做任何你想做的事情,你只是想小心翼翼地去做。这个解决方案对我有用,我更喜欢它,因为无论如何我都使用那个架构。 实际上我最终扩展了 Application 类并将我的数据模型存储在那里。在 Intents 中,我只传递了数据对象的 ID,可用于从 Application 类中检索原始对象。如果数据模型通过标准侦听器概念发生变化,扩展应用程序类也会通知所有使用数据模型的对象。我知道这仅适合我需要在整个应用程序上共享数据模型的情况,但对于这种情况,它是完美的,也不需要静态类和字段!【参考方案20】:

感谢您的帮助,但我找到了另一种可选解决方案

 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 虽然可以在竞争中引入 Serializable,但是 Parcellables 更快...【参考方案21】:

我知道这有点晚了,但是如果您只想对几个对象执行此操作,为什么不在目标活动中将您的对象声明为公共静态对象?

public static myObject = new myObject();

从你的源活动中给它一个值?

destinationActivity.myObject = this.myObject;

在您的源活动中,您可以像使用任何全局对象一样使用它。 对于大量对象,它可能会导致一些内存问题,但对于少数对象,我认为这是最好的方法

【讨论】:

将任何对象设为静态会将其标记为活动对象。 JVM 和 DVM 将在完成时跳过清理该资源(标记和哭泣算法)。因此,您需要手动将该对象清空以进行内存管理。简而言之,这不是一个好方法 我已经明确表示这种方法可能会导致一些内存问题....但是对于一两个对象,您可以手动将其设置为 null,没什么大不了的! 如果您对创建静态对象的限制没问题,您可以使用。【参考方案22】:

如果您对使用 putExtra 功能不是很讲究,只是想用对象启动另一个活动,您可以查看我编写的 GNLauncher (https://github.com/noxiouswinter/gnlib_android/wiki#gnlauncher) 库,以使这个过程更直接。

GNLauncher 使从另一个 Activity 等向 Activity 发送对象/数据就像在 Activity 中使用所需数据作为参数调用函数一样简单。它引入了类型安全并消除了必须序列化、使用字符串键附加到意图并在另一端撤消相同的所有麻烦。

【讨论】:

【参考方案23】:

你的类应该实现 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

【讨论】:

你的类必须实现Serializable是错误的。例如,该类可以实现Parcelable Parcelable 和 Serializable @Kernald 有什么区别?就处理时间而言,它是否更慢/不是最佳实践或其他什么? Serializable 是标准 Java 接口,Parcelable 是特定于 Android 的。在性能方面,Parcelable 更高效:developerphil.com/parcelable-vs-serializable【参考方案24】:

您可以使用 android BUNDLE 来执行此操作。

从您的类中创建一个 Bundle,例如:

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

    return b;

然后用 INTENT 传递这个包。 现在你可以通过传递 bundle 来重新创建你的类对象

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

在您的自定义类中声明它并使用。

【讨论】:

更喜欢直接 Parcelable 实现,恕我直言。 Bundle 自己实现 Parcelable,因此您仍然可以获得性能提升,同时避免自己实现它的所有麻烦。相反,您可以使用键值对来存储和检索数据,这比仅仅依靠顺序更可靠。 Parcelable 对我来说似乎很复杂,在我上面的答案中,我在它的对象上使用类中的 toBundle 方法,因此对象被转换为包,然后我们可以使用构造函数将包转换为类对象。 此解决方案仅在您通过意图传递单个对象时才可行。 像 json 但我认为 json 很轻。 我检索到的对象是同一个对象还是副本?【参考方案25】:
Intent i = new Intent();
i.putExtra("name_of_extra", myParcelableObject);
startACtivity(i);

【讨论】:

【参考方案26】:

创建 Android 应用程序

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

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

包:com.hmkcode.android

保留其他默认选择,继续下一步直到完成

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

Person.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_
android:layout_
android:orientation="vertical"
tools:context=".MainActivity" >

<LinearLayout
    android:layout_
    android:layout_
    android:orientation="horizontal">
    <TextView
        android:id="@+id/tvName"
        android:layout_
        android:layout_
        android:layout_gravity="center"
        android:gravity="center_horizontal"
        android:text="Name" />

    <EditText
        android:id="@+id/etName"
        android:layout_
        android:layout_

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

<LinearLayout
     android:layout_
    android:layout_
    android:orientation="horizontal">
<TextView
    android:id="@+id/tvAge"
    android:layout_
    android:layout_
    android:layout_gravity="center"
    android:gravity="center_horizontal"
    android:text="Age" />
<EditText
    android:id="@+id/etAge"
    android:layout_
    android:layout_
    android:ems="10" />
</LinearLayout>

<Button
    android:id="@+id/btnPassObject"
    android:layout_
    android:layout_
    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_
android:layout_
android:orientation="vertical"
 >

<TextView
    android:id="@+id/tvPerson"
    android:layout_
    android:layout_
    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());



【讨论】:

【参考方案27】:

在您的第一个活动中:

intent.putExtra("myTag", yourObject);

在你的第二个中:

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

别忘了让你的自定义对象可序列化:

public class myCustomObject implements Serializable 
...

【讨论】:

Parcelable 比 Serializable 好!避免在你的 Android 代码中使用 Serializable!【参考方案28】:

你可以通过intent发送序列化对象

// 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 
 

【讨论】:

您也可以通过 Intent 发送 Parcelable 对象。 “Serializable 在 Android 上的速度慢得可笑。事实上,边界线在许多情况下是无用的。”看***.com/questions/5550670/… 如果activity已经在运行了,是否需要做startActivity(i); ?我的意思是,我可以让 activity A 调用 activity B,并将数据返回给 activity A 吗?我很困惑吗? @Seraphim 的性能在序列化大量对象时很重要,但如果序列化一个对象需要 1 毫秒或 10 毫秒,用户不会注意到。如果 Intent extra 已经是 Serializable 但不是 Parcelable,那么很少值得麻烦将其设置为 Parcelable【参考方案29】:

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

Here 是 Dianne Hackborn(hackbod - Google Android 软件工程师)对此事的看法:

对于您知道活动以相同方式运行的情况 过程中,您可以通过全局变量共享数据。例如,你 可以有一个全球HashMap&lt;String, WeakReference&lt;MyInterpreterState&gt;&gt; 当你创建一个新的 MyInterpreterState 时,你会想出一个唯一的名字 并将其放入哈希映射中;将该状态发送给另一个 活动,只需将唯一名称放入哈希映射中,当 第二个活动开始了,它可以从中检索 MyInterpreterState 带有它接收到的名称的哈希映射。

【讨论】:

是的,我觉得奇怪的是我们得到了这些要使用的 Intent,然后一位***工程师告诉我们只对我们的数据使用全局变量。但它是直接从马嘴里出来的。 这里的弱引用不会成为垃圾收集的受害者吗? @uLYsseus 认为是这个想法,一旦你在活动中完成了它们......所以当相关活动被破坏时,它会允许它 gc @RichardLeMesurier 我也在想同样的事情,但后来我查看了 Dianne Hackborn 上面引用的 Google Groups 帖子,她提到全局变量真正唯一的问题是使用隐式意图(其中可以在你的包之外启动一个活动)。正如 Dianne 所提到的,这是有道理的,因为这些活动很可能对您传递给它们的自定义类型的了解为零。读完之后,我就更清楚为什么在这种情况下 globals 可能不是那么糟糕的路线,我想我会分享一下,以防其他人也好奇 意图被过度设计到可以将意图传递到另一台计算机的程度。当您实际上只有一个正在处理的进程时,这显然不是做任何事情的好方法。它不好的原因:内存使用,cpu使用,电池使用。最后一个特别是在事后看来,其意图相当令人困惑。有些人坚持认为这是个好主意,通常是因为“谷歌这么说”。【参考方案30】:

如果你的对象类实现了Serializable,你不需要做任何其他事情,你可以传递一个可序列化的对象。 这就是我使用的。

【讨论】:

以上是关于如何使用 Intents 将对象从一个 Android Activity 发送到另一个?的主要内容,如果未能解决你的问题,请参考以下文章

如何调试我的 Siri (Intents) 扩展?

xml 使用Android Intents从图库/相机中拾取图像的实用程序

我可以对 Intents 和 List 视图做些啥

Discord Bot - 无法从 Intents 访问 FLAGS

java 在Android测试中如何使用espresso-intents的示例

如何在“new Intent(ContactsContract.Intents.Insert.ACTION)”启动的 Activity 完成后刷新我的 ListView?