我有一个活动,它是整个应用程序中使用的主要活动,它有许多变量。我有另外两个活动,我希望能够使用来自第一个活动的数据。 现在我知道我可以这样做:

GlobalState gs = (GlobalState) getApplication();
String s = gs.getTestMe();

然而,我想要分享很多变量,其中一些可能相当大,所以我不想像上面那样创建它们的副本。

是否有一种方法可以直接获取和更改变量而不使用get和set方法?我记得在谷歌开发网站上读过一篇文章,说不建议在Android上使用这种性能。


当前回答

做谷歌命令你做的事!: http://developer.android.com/resources/faq/framework.html # 3

基本数据类型 非持久化对象 单例类-我最喜欢的:D 一个公共静态字段/方法 对象弱引用的HashMap 持久对象(应用程序首选项,文件,内容提供程序,SQLite DB)

其他回答

假设你使用Intent从活动一调用活动二。 你可以通过intent.putExtra()传递数据,

拿着这个作为你的参考。 使用Intent.putExtra发送数组

希望这是你想要的。

做谷歌命令你做的事!: http://developer.android.com/resources/faq/framework.html # 3

基本数据类型 非持久化对象 单例类-我最喜欢的:D 一个公共静态字段/方法 对象弱引用的HashMap 持久对象(应用程序首选项,文件,内容提供程序,SQLite DB)

“然而,我想分享很多 变量,有些可能是 很大,所以我不想创造 像上面这样的副本。”

这并不会产生复制(特别是对于String,但即使对象也是通过引用的值传递的,而不是对象本身,像这样的getter是可以使用的——可以说比其他方法更好使用,因为它们是常见的和易于理解的)。旧的“性能神话”,比如不使用getter和setter,仍然有一些价值,但也在文档中更新了。

但如果你不想那样做,你也可以让变量在GlobalState中为public或protected,然后直接访问它们。并且,你可以创建一个静态单例,就像Application对象JavaDoc指出的那样:

通常不需要子类化 应用程序。在大多数情况下, 静态单例也可以提供同样的功能 以更模块化的方式实现功能。 如果你的单例需要全局 上下文(例如注册 广播接收机),功能到 检索时可以给它一个Context 内部使用 Context.getApplicationContext()时 首先构造单例。

使用Intent数据是传递数据的另一种方式,但它通常用于较小的数据和简单类型。您可以传递更大/更复杂的数据,但这比使用静态单leon更复杂。不过,Application对象仍然是我个人最喜欢的在Android应用程序组件之间共享更大/更复杂的非持久性数据的对象(因为它在Android应用程序中有一个定义良好的生命周期)。

另外,正如其他人所注意到的,如果数据变得非常复杂并且需要持久化,那么您也可以使用SQLite或文件系统。

以下是实现这一目标最常见的方法:

在意图内发送数据 静态字段 WeakReferences的HashMap 持久化对象(sqlite、共享首选项、文件等)

TL;DR:共享数据有两种方式:在意图的附加中传递数据或将数据保存在其他地方。如果数据是原语、字符串或用户定义的对象:将其作为意图附加的一部分发送(用户定义的对象必须实现Parcelable)。如果传递复杂对象,则将实例保存在其他地方的单例中,并从启动的活动中访问它们。

一些如何以及为什么实现每种方法的例子:

在意图内发送数据

Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
intent.putExtra("some_key", value);
intent.putExtra("some_other_key", "a value");
startActivity(intent);

关于第二个活动:

Bundle bundle = getIntent().getExtras();
int value = bundle.getInt("some_key");
String value2 = bundle.getString("some_other_key");

如果要传递基元数据或字符串,请使用此方法。您还可以传递实现Serializable的对象。

虽然很诱人,但在使用Serializable之前应该三思:它很容易出错,而且非常慢。所以一般来说:如果可能的话,远离Serializable。如果您想传递复杂的用户定义对象,请查看Parcelable接口。它更难实现,但与Serializable相比,它有相当大的速度提升。

共享数据而不持久化到磁盘

在大多数情况下,两个活动都运行在同一个进程中,因此可以通过将数据保存在内存中来在活动之间共享数据。

注意:有时候,当用户离开你的activity时(没有退出),Android可能会决定终止你的应用程序。在这种情况下,我有经验的情况下,android试图启动最后一个活动使用的意图提供之前的应用程序被杀死。在这种情况下,存储在单例(您的或应用程序)中的数据将消失,可能会发生糟糕的事情。为了避免这种情况,要么将对象持久化到磁盘,要么在使用数据之前检查数据以确保其有效。

使用单例类

有一个类来保存数据:

public class DataHolder {
  private String data;
  public String getData() {return data;}
  public void setData(String data) {this.data = data;}

  private static final DataHolder holder = new DataHolder();
  public static DataHolder getInstance() {return holder;}
}

从启动的活动:

String data = DataHolder.getInstance().getData();

使用单例应用程序

应用单例是android.app.Application的一个实例,它是在应用启动时创建的。你可以通过扩展Application来提供一个自定义的:

import android.app.Application;
public class MyApplication extends Application {
  private String data;
  public String getData() {return data;}
  public void setData(String data) {this.data = data;}
}

活动开始前:

MyApplication app = (MyApplication) getApplicationContext();
app.setData(someData);

然后,从启动的活动中:

MyApplication app = (MyApplication) getApplicationContext();
String data = app.getData();

静态字段

其思想基本上与单例相同,但在这种情况下,你提供了对数据的静态访问:

public class DataHolder {
  private static String data;
  public static String getData() {return data;}
  public static void setData(String data) {DataHolder.data = data;}
}

从启动的活动:

String data = DataHolder.getData();

WeakReferences的HashMap

同样的想法,但是允许垃圾收集器删除未引用的对象(例如当用户退出活动时):

public class DataHolder {
  Map<String, WeakReference<Object>> data = new HashMap<String, WeakReference<Object>>();

  void save(String id, Object object) {
    data.put(id, new WeakReference<Object>(object));
  }

  Object retrieve(String id) {
    WeakReference<Object> objectWeakReference = data.get(id);
    return objectWeakReference.get();
  }
}

活动开始前:

DataHolder.getInstance().save(someId, someObject);

从启动的活动:

DataHolder.getInstance().retrieve(someId);

你可能需要也可能不需要使用意图的附加来传递对象id。这完全取决于你的具体问题。

将对象持久化到磁盘

其思想是在启动其他活动之前将数据保存到磁盘中。

优点:您可以从其他地方启动活动,如果数据已经被持久化,那么它应该可以正常工作。

缺点:它很麻烦,需要更多的时间来实现。需要更多的代码,因此更有可能引入错误。它也会慢得多。

持久化对象的一些方法包括:

将它们保存到共享首选项 将它们保存到sqlite数据库中 将它们保存到一个文件中(我会避免这个文件)

我有一些想法,但我不知道它们是否是你想要的。

您可以使用一个保存所有数据的服务,然后将活动绑定到该服务以进行数据检索。

或者将您的数据打包为可序列化或可打包的,并将它们附加到一个bundle中,并在活动之间传递该bundle。

这可能根本不是你要找的,但你也可以尝试使用SharedPreferences或一般的首选项。

不管怎样,让我知道你的决定。