1

用头撞墙。我正在从 Blackberry 转换为 Android。

我有一个需要保留日志的应用程序。这是一个简单的 ArrayList,不会那么大。它确实需要在应用程序重新启动等之间持续存在。但它还不够复杂,无法使用 SQL。它需要在 ListView 中显示,因此 ArrayList 似乎最简单。

我似乎能够很容易地序列化和存储 ArrayList。但是在读回它时,它会说我不能从 Object 转换为 ArrayList。

我的计划是让日志对象(单例)在我获取实例时加载历史记录。然后我会用 onDestroy() 将它写入一个文件...

在黑莓上,这种事情很容易。我很惊讶你需要在 Android 上做多少工作。Android上的其他一切似乎都更容易。我更喜欢将对象标记为持久并让系统为我管理它的方法。我知道您也不能轻易地将对象填充到 SharedPreference 中。

有人可以指出我哪里出错了吗?我已经重新连接了几种方法,但问题仍然存在。如果有更简单的方法,请告诉。

谢谢

我有:

public class DataLog implements Serializable {
    private static final long serialVersionUID = 0L;
    private static String fileName = "datalog.dat";

    private static ArrayList<String> log = null;

    static public ArrayList<String> getInstance() {
        if (log == null) {
            synchronized (DataLog.class) {
                if (log == null) {
                    log = new ArrayList<String>();
                }
            }
            load();
        }
        return log;
    }

    public DataLog() {
        super();
    }

    public boolean add(String entry) {
        return log.add(entry);
    }

    public void add(int index, String entry) {
        if (index > 0)
            log.add(index, entry);
        else
            log.add(entry);
        save();
    }

    public void clear() {
        log.clear();
    }
    public void save() {
        Persister.store(fileName, log);
    }

    public static void load() {
        log = (ArrayList<String>) Persister.restore(fileName);
    }
}

public class Persister {
    static Context context = ThisApplication.context;

    public Persister() {}

    public static boolean store(String fileName, Object obj){
        File file = context.getFileStreamPath(fileName);

        FileOutputStream fos = null;
        ObjectOutputStream oos = null;
        try {
            fos = new FileOutputStream(file);
            oos = new ObjectOutputStream(fos);
            oos.writeObject(obj);
            oos.close();
            fos.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        return true;

    }
    public static Object restore(String fileName){
        File file = context.getFileStreamPath(fileName);
        Object obj = new Object();

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

1 回答 1

0

如果该文件不存在,那么Persister.restore实际上会返回一个new Object(),它不是 的一个实例ArrayList。你可以这样做:

public static ArrayList<String> restore(String fileName){
    File file = context.getFileStreamPath(fileName);
    ArrayList<String> obj = null; // returning null indicates error

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

然后,您可以消除演员表load()(因为它现在在Persister.restore):

public static void load() {
    log = Persister.restore(fileName);
}

我还将更改Persister.store()为接受显式ArrayList<String>参数而不是一般参数Object

public static boolean store(String fileName, ArrayList<String> obj){
    // method body does not need to change
}

这样,编译器将捕获您尝试保留除ArrayList<String>.

于 2013-08-12T16:29:32.470 回答