以下是一些实现此目的最常见的方法:
- 将数据放入意图中
- 静态字段
WeakReferences
哈希映射
- 持久化对象(例如sqlite、共享首选项、文件等)
简而言之:有两种共享数据的方式:将数据作为意图额外信息传递或将其保存在其他位置。如果数据是原始类型、字符串或用户定义的对象,请将其作为意图额外信息的一部分发送(用户定义的对象必须实现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相比,它具有相当大的速度优势。
在不持久化到磁盘的情况下共享数据
通过将数据保存在内存中,可以在活动之间共享数据,因为在大多数情况下,这两个活动运行在同一个进程中。
注意:有时,当用户离开你的活动(未退出)时,Android可能会决定终止你的应用程序。在这种情况下,我曾经遇到过一些情况,即Android试图使用在应用程序被终止之前提供的意图来启动最后一个活动。在这种情况下,存储在单例中的数据(无论是你的还是Application的)都将消失,可能会发生不良事件。为了避免这种情况,您可以将对象持久化到磁盘上,或在使用数据之前检查数据以确保其有效。
使用单例类
创建一个类来保存数据:
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);
根据你的具体问题,你可能需要使用Intent的extras传递对象ID,也可能不需要。
将对象持久化到磁盘
这个想法是在启动其他活动之前将数据保存到磁盘上。
优点:您可以从其他位置启动活动,并且如果数据已经持久化,它应该能够正常工作。
缺点:它很麻烦,实现需要更多时间。需要更多的代码,因此引入错误的机会更大。它还会变慢。
一些将对象持久化的方法包括: