0

我有一个 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);

活动 onResume:

dataLog = Persister.recoverLog(this, "datalog.dat");
dataLogAdapter = new ArrayAdapter<String>(this,R.layout.log_row, dataLog);
logView.setAdapter(dataLogAdapter);

坚持:

public static DataLog recoverLog(Context context, String fileName){
File file = context.getFileStreamPath(fileName);
DataLog obj = new DataLog ();

if(file.exists() && file.length()>0){
    FileInputStream fis = null;
    ObjectInputStream ois = null;
    try {
        fis = new FileInputStream(file);
        ois = new ObjectInputStream(fis);
        obj = (DataLog) ois.readObject();
        ois.close();
        fis.close();
    } catch (IOException ex) {
        ex.printStackTrace();
    } catch (ClassNotFoundException ex) {
        ex.printStackTrace();
    }
}
return obj;
}

数据记录:

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

}
4

1 回答 1

0

您的数据记录不是真正的单身人士。如果是,则在第一次创建后不会创建新的引用。

这个:

dataLog = Persister.recoverLog(this, "datalog.dat");

不应该返回一个Datalog但一些内部数据DataLog使用(字符串的 ArrayList)并且应该在内部调用DataLog

然后传递 dataLog 实例。如果您重新分配它,您将遇到问题。当您重新加载数据日志时,您需要重新加载依赖于 DataLog 的数组实例的结构。

如有必要,处理重新加载DataLog数据onResume,但要这样做:

DataLog.getInstance().load();

这样您的数据日志就不会被重新分配。那是关键。DataLog 是数据的包装器。如果 DataLog 的内部状态发生更改,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();
    }
}
于 2013-08-15T14:17:24.300 回答