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

客户类别的代码:

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

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

我怎样才能做到这一点?


当前回答

从此活动启动另一个活动,并通过捆绑对象传递参数

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

其他回答

我写了一个名为intentparser的库

它真的很容易使用将此添加到项目等级

allprojects {
        repositories {
            ...
            maven { url 'https://jitpack.io' }
        }
    }

将此添加到应用程序等级


dependencies {
            implementation 'com.github.lau1944:intentparser:v$currentVersion'
    }

使用扩展方法putObject传递对象

val testModel = TestModel(
            text = "hello world",
            isSuccess = false,
            testNum = 1,
            textModelSec = TextModelSec("second model")
)
startActivity(
     Intent(this, ActivityTest::class.java).apply {
          this.putObject(testModel)
     }
) 

从上一个活动获取对象


val testModel = intent.getObject(TestModel::class.java)

正如在评论中提到的,这个答案打破了封装并紧密耦合了组件,这很可能不是您想要的。最好的解决方案可能是使对象可Parcelable或Serializable,正如其他响应所解释的那样。话虽如此,解决方案解决了问题。所以,如果你知道你在做什么:

使用带有静态字段的类:

public class Globals {
    public static Customer customer = new Customer();
}

在活动内部,您可以使用:

活动来源:

Globals.customer = myCustomerFromActivity;

活动目标:

myCustomerTo = Globals.customer;

这是传递活动信息的简单方法。

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

A.数据库

B.共享偏好。

C.对象序列化。

可以保存公共数据的类可以命名为公共实用程序。这取决于你。

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

这取决于您的项目需求。

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

使用putString()、putBoolean()、put Int()、putFloat()和putLong(),可以保存所需的数据类型。

如何获取

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

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

C.对象序列化

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

使用Javabean并将其存储为他的一个字段,并使用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);

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

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

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

如果您需要此教程,请参阅:

Java序列化(博客文章)获取其他类中的变量(堆栈溢出)

D.公用设施

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

样品

public class CommonUtilities {

    public static String className = "CommonUtilities";

}

E.通过意图传递数据

有关传递数据的选项,请参考教程Android–使用Parcelable类在活动之间传递包裹数据。

我一直想知道为什么这不能像调用其他活动的方法一样简单。我最近写了一个实用程序库,使它几乎如此简单。你可以在这里查看(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有关如何添加依赖项的信息。

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

实施Parcelable实现可串行化使用某种轻量级事件总线库(例如,Greenrobot的EventBus或Square的Otto)

Parcelable-快速且符合Android标准,但它有很多样板代码,并且需要硬编码字符串以供在提取意图值(非强类型)时参考。

可序列化-接近于零样板,但这是最慢的方法,并且在从意图中提取值(非强类型)时还需要硬编码字符串。

事件总线-零样板,最快的方法,不需要硬编码字符串,但它需要额外的依赖项(虽然通常很轻,约40 KB)

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