以下是实现这一目标最常见的方法:
在意图内发送数据
静态字段
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数据库中
将它们保存到一个文件中(我会避免这个文件)