从磁盘重新加载java对象而不创建新实例?
我有一个Android应用程序,它在扩展ArrayList的自定义对象中保存事件的持久日志。它保存在一个单例中,以便各种活动都指向同一个日志。主活动将重新加载onResume中的列表 问题是,当我重新加载日志时,所有UI元素(如ArrayAdapter)都会丢失引用,我需要重新设置它们。它起作用了。但是,这似乎需要做很多工作 如何将对象重新加载到原始对象的实例中,以便不必再次执行所有设置?使用单例应该更容易,而不是更难 我知道这都是参考传递的问题。但我就是想不起来 Java不是我的第一语言。。。谢谢 创建时的活动:从磁盘重新加载java对象而不创建新实例?,java,android,android-activity,android-adapter,Java,Android,Android Activity,Android Adapter,我有一个Android应用程序,它在扩展ArrayList的自定义对象中保存事件的持久日志。它保存在一个单例中,以便各种活动都指向同一个日志。主活动将重新加载onResume中的列表 问题是,当我重新加载日志时,所有UI元素(如ArrayAdapter)都会丢失引用,我需要重新设置它们。它起作用了。但是,这似乎需要做很多工作 如何将对象重新加载到原始对象的实例中,以便不必再次执行所有设置?使用单例应该更容易,而不是更难 我知道这都是参考传递的问题。但我就是想不起来 Java不是我的第一语言。。。
dataLog = DataLog.getInstance();
logView = (ListView) findViewById(R.id.logView);
dataLogAdapter = new ArrayAdapter<String>(this,R.layout.log_row, dataLog);
logView.setAdapter(dataLogAdapter);
数据日志:
public class DataLog extends ArrayList<String> implements Serializable {
private static final long serialVersionUID = 0L;
public DataLog() {}
private static DataLog _instance;
public static DataLog getInstance() {
if(_instance==null){
_instance = new DataLog();
}
return _instance;
}
public boolean add(String entry) {
super.add(entry);
return true;
}
public void add(int index, String entry) {
if (index > 0)
super.add(index, entry);
else
super.add(entry);
}
public void clear() {
super.clear();
}
}
公共类数据日志扩展ArrayList实现可序列化{
私有静态最终长serialVersionUID=0L;
公共数据日志(){}
私有静态数据日志_实例;
公共静态数据日志getInstance(){
if(_instance==null){
_实例=新数据日志();
}
返回_实例;
}
公共布尔添加(字符串项){
super.add(条目);
返回true;
}
公共void add(int索引、字符串条目){
如果(索引>0)
super.add(索引、条目);
其他的
super.add(条目);
}
公共空间清除(){
super.clear();
}
}
您的数据日志不是真正的单例。如果是,则在第一次创建引用后不会创建新引用
这:
不应返回数据日志
,但某些内部数据数据日志
使用(字符串数组列表),应在数据日志
然后只传递数据日志实例。如果你重新分配它,你会有问题的。重新加载数据日志时,需要根据数据日志的数组实例重新加载结构
如有必要,在恢复中重新加载数据日志
数据,但要这样做:
DataLog.getInstance().load();
这样您的数据日志就不会被重新分配。这是关键。数据日志是数据的包装器。如果数据日志的内部状态发生更改,则不会丢失对DataLog
的引用
下面是一个例子:
public class DataLog implements Serializable {
//internalize this data.
private ArrayList<String> data;
private static final long serialVersionUID = 0L;
//singleton's constructor should be private.
private DataLog() {}
private static DataLog _instance;
public static DataLog getInstance() {
if(_instance==null){
_instance = new DataLog();
}
return _instance;
}
public ArrayList<String> getData(){
//copy this if you're worried about it being modified.
//DO NOT pass this reference around. Pass a reference to data log,
//reload GUI relying on this reference as needed.
return data;
}
public void load(){
data = //reload string array from disk.
}
public boolean add(String entry) {
super.add(entry);
return true;
}
public void add(int index, String entry) {
if (index > 0)
data.add(index,entry);
else
data.add(entry);
}
public void clear() {
data.clear();
}
}
公共类数据日志实现可序列化{
//将这些数据内部化。
私有数组列表数据;
私有静态最终长serialVersionUID=0L;
//singleton的构造函数应该是私有的。
私有数据日志(){}
私有静态数据日志_实例;
公共静态数据日志getInstance(){
if(_instance==null){
_实例=新数据日志();
}
返回_实例;
}
公共ArrayList getData(){
//如果您担心它被修改,请复制此文件。
//不要传递此引用。传递对数据日志的引用,
//根据需要重新加载依赖于此引用的GUI。
返回数据;
}
公共空荷载(){
data=//从磁盘重新加载字符串数组。
}
公共布尔添加(字符串项){
super.add(条目);
返回true;
}
公共void add(int索引、字符串条目){
如果(索引>0)
添加数据(索引、条目);
其他的
数据。添加(条目);
}
公共空间清除(){
data.clear();
}
}
按引用传递不会有问题,Java是按值传递的。与其序列化对象,不如一个接一个地序列化字符串条目?如果您实际使用的是单例,那么“单例”可能会更容易。由于您正在使用Persister重新创建新实例,当然您必须让所有对象都知道新引用。@JasonC确切地说,我在回答中已经谈到了这一点。小心;如果您从getInstance()
调用recoverLog()
“只要有必要”,那么这意味着实例
可以更改,这很好,但这意味着您希望传递getInstance()
,而不是传递实例本身,以免保留旧的,不再是有效的参考资料。谢谢@JasonC我已经解释得更清楚了。抢手货我希望人们能在评论上获得投票权……啊。这是有道理的。所以问题是我不能扩展ArrayList,而是在内部包含一个ArrayList,我可以在不影响外部引用的情况下对其进行操作。我怀疑会是那样的,但在细节中迷失了方向。谢谢
dataLog = Persister.recoverLog(this, "datalog.dat");
DataLog.getInstance().load();
public class DataLog implements Serializable {
//internalize this data.
private ArrayList<String> data;
private static final long serialVersionUID = 0L;
//singleton's constructor should be private.
private DataLog() {}
private static DataLog _instance;
public static DataLog getInstance() {
if(_instance==null){
_instance = new DataLog();
}
return _instance;
}
public ArrayList<String> getData(){
//copy this if you're worried about it being modified.
//DO NOT pass this reference around. Pass a reference to data log,
//reload GUI relying on this reference as needed.
return data;
}
public void load(){
data = //reload string array from disk.
}
public boolean add(String entry) {
super.add(entry);
return true;
}
public void add(int index, String entry) {
if (index > 0)
data.add(index,entry);
else
data.add(entry);
}
public void clear() {
data.clear();
}
}