【问题标题】:How to store a class object into Internal Memory Storage using serializable?如何使用可序列化将类对象存储到内部存储器中?
【发布时间】:2012-04-07 20:43:09
【问题描述】:

我需要将此对象存储到手机的内部存储器中,并且我在清单上设置了<uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE"></uses-permission>。对象本身有两个静态方法用于从内部存储器中存储和重新加载它:

public class SaveState implements Serializable {
static public List<FullMagazine> fms = new ArrayList<FullMagazine>();
static SaveState instance=null;

public static SaveState getInstance(){      
    if( instance == null )
        instance = new SaveState();     
    return instance;
}

public static void saveData(SaveState instance){
    ObjectOutput out;
    try {
        out = new ObjectOutputStream(new FileOutputStream("appSaveState.data"));        
        out.writeObject(instance);
        out.close();
    } catch (Exception e) {e.printStackTrace();}
}

public static SaveState loadData(){
    ObjectInput in;
    SaveState ss=null;
    try {
        in = new ObjectInputStream(new FileInputStream("appSaveState.data"));       
        ss=(SaveState) in.readObject();
        in.close();
    } catch (Exception e) {e.printStackTrace();}
    return ss;
}
}

我正在尝试在我的活动中使用此调用存储它并重新打开它:

            SaveState.fms.add(fm);
            SaveState.saveData(SaveState.getInstance());                
            SaveState sv = SaveState.loadData();

但是它不起作用,它没有存储对象,当然它也没有读取对象,我在存储和读取对象时遇到了这两个异常:

    03-23 09:18:16.702: WARN/System.err(9060): java.io.FileNotFoundException: /appSaveState.data (Read-only file system)
03-23 09:18:16.702: WARN/System.err(9060):     at org.apache.harmony.luni.platform.OSFileSystem.openImpl(Native Method)
03-23 09:18:16.702: WARN/System.err(9060):     at org.apache.harmony.luni.platform.OSFileSystem.open(OSFileSystem.java:152)
03-23 09:18:16.702: WARN/System.err(9060):     at java.io.FileOutputStream.<init>(FileOutputStream.java:97)
03-23 09:18:16.702: WARN/System.err(9060):     at java.io.FileOutputStream.<init>(FileOutputStream.java:168)
03-23 09:18:16.702: WARN/System.err(9060):     at java.io.FileOutputStream.<init>(FileOutputStream.java:147)
03-23 09:18:16.702: WARN/System.err(9060):     at com.Magazine.SaveState.saveData(SaveState.java:35)
03-23 09:18:16.702: WARN/System.err(9060):     at com.Magazine.MainMenu$DownloadThread.run(MainMenu.java:807)
03-23 09:18:16.709: WARN/System.err(9060): java.io.FileNotFoundException: /appSaveState.data (No such file or directory)
03-23 09:18:16.709: WARN/System.err(9060):     at org.apache.harmony.luni.platform.OSFileSystem.openImpl(Native Method)
03-23 09:18:16.709: WARN/System.err(9060):     at org.apache.harmony.luni.platform.OSFileSystem.open(OSFileSystem.java:152)
03-23 09:18:16.709: WARN/System.err(9060):     at java.io.FileInputStream.<init>(FileInputStream.java:82)
03-23 09:18:16.709: WARN/System.err(9060):     at java.io.FileInputStream.<init>(FileInputStream.java:134)
03-23 09:18:16.709: WARN/System.err(9060):     at com.Magazine.SaveState.loadData(SaveState.java:46)
03-23 09:18:16.709: WARN/System.err(9060):     at com.Magazine.MainMenu$DownloadThread.run(MainMenu.java:809)

代码有什么问题?

谢谢

【问题讨论】:

  • 问题是你正在尝试写入 / 在 android 中是只读的。
  • 静态List中使用的类,FullMagazine是否也实现了Serializable?

标签: java android serialization objectoutputstream


【解决方案1】:

您不能只写入内部存储空间(即使您获得了该权限)。 尝试使用外部 sd 或您的 cache folder

【讨论】:

  • 缓存文件夹数据在从手机中卸载应用程序之前一直存在?请告诉我如何使用缓存文件夹,我应该将什么更改为我的代码?
  • 文件 cacheFile = new File(activity.getCacheDir(), "appSaveState.data"); - 像以前一样写入该文件。
  • 缓存文件夹在可用空间变低时容易被操作系统删除!
【解决方案2】:

改变这个

out = new ObjectOutputStream(new FileOutputStream("appSaveState.data"));

   File outFile = new File(Environment.getExternalStorageDirectory(), "appSaveState.data");
   out = new ObjectOutputStream(new FileOutputStream(outFile)); 

正如@e-x 正确指出的那样,在清除应用程序数据或卸载应用程序时不会删除该文件

【讨论】:

  • 如果手机没有安装 SDCARD 会怎样?我正在尝试将其存储在内部存储器中,因为我必须将这些数据存储在所有手机上,包括没有 SDCARD 的手机
  • 如果您指的是不支持 sdcard 的手机(如 samsung nexus),Enviromenet.getExternalStorageDirectory() 将返回手机内部存储存档的路径。
  • 我觉得值得一提的是,如果手机有SDCARD,那么在清除应用程序数据时,文件会保留。
  • @E_X,我更新了答案,感谢贡献
【解决方案3】:

这是我基于这篇文章和this的方法

我在我的用户类上写了这个

private static File mFolder;
public void saveData(Activity pContext) {
    //this could be initialized once onstart up
    if(mFolder == null){
        mFolder = pContext.getExternalFilesDir(null);
    }
    this.save();
    ObjectOutput out;
    try {
        File outFile = new File(mFolder,
                "someRandom.data");
        out = new ObjectOutputStream(new FileOutputStream(outFile));
        out.writeObject(this);
        out.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

public static User loadData(Context pContext) {
    if(mFolder == null){
        mFolder = pContext.getExternalFilesDir(null);
    }
    ObjectInput in;
    User lUser = null;
    try {
        FileInputStream fileIn = new FileInputStream(mFolder.getPath() + File.separator + "someRandom.data");
        in = new ObjectInputStream(fileIn);
        lUser = (User) in.readObject();
        in.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
    if (lUser != null) {
        lUser.save();
        Log.d("current User: ", lUser.nickname);
    } else {
        Log.d("current User: ", "null");
    }
    return lUser;
}

编辑:

然后从我的活动中调用

mUser = User.loadData(mSelf);

mUser = User.loadData(this);

mSelf 将是我存储的实例

希望这会有所帮助:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-08-05
    • 2021-01-28
    • 1970-01-01
    • 2015-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多