5
  Bundle bundle;
  //set data to bundle
  //......


  File file = new File(context.getFilesDir().getAbsolutePath()  + "/data/");
                FileOutputStream fos;
                try {
                     fos = new FileOutputStream(file);
                     //fos.write
                     fos.close();
                } catch (FileNotFoundException exp1) {
                    exp1.printStackTrace();
                } catch ( IOException exp2) {
                    exp2.printStackTrace();
                }

我有上述代码。我要做的就是将捆绑包保存到文件中。我找到了 write 方法,但我不能传递一个包,而只能传递一个字节 []。我试图将包转换为字节 [],但我没有成功。我应该怎么做才能使这项工作?最有效的方法是什么?

4

7 回答 7

5

没有通用的方法可以从持久存储中保存和恢复包。这是因为 Parcel 类不提供任何 android 版本兼容性保证。所以我们最好不要序列化它。

但如果你真的想要,你可以通过 Parceable 接口对 Bundle 进行序列化。将 bundle 转换为 Parcel (writeToParcel()/readFromParcel()),然后使用 Parcel 的 marshall() 和 unmarshall() 方法获取 byte[]。保存/加载字节数组到文件。但是有一个机会,有一天你将无法恢复你的数据,以防用户将他的 Android 操作系统更新到更新的版本。

使用 ObjectOutput/InputStream 序列化捆绑包有一种合法但非常复杂且不可靠的方法。(获取所有键,遍历键并将可序列化的键=值对保存到文件中,然后从文件中读取键=值对,确定值的类型,通过适当的 putXXX(key, value) 方法将数据放回 Bundle)但它是不值得 )

我建议您将自定义可序列化结构放在 Bundle 中,以在其中存储所有必需的值,并仅从文件中保存/加载此结构。

或者找到一种更好的方法来管理您的数据,而无需使用 Bundle。

于 2013-01-10T11:36:34.157 回答
4

我不喜欢上面评论中代码的格式,所以这就是您将其读回的方式:

像这样阅读它:

try {
    FileInputStream fis = openFileInput(localFilename);
    byte[] array = new byte[(int) fis.getChannel().size()];
    fis.read(array, 0, array.length);
    fis.close();
    parcel.unmarshall(array, 0, array.length);
    parcel.setDataPosition(0);
    Bundle out = parcel.readBundle();
    out.putAll(out);
} catch (FileNotFoundException fnfe) {
} catch (IOException ioe) {
} finally {
    parcel.recycle();
}
于 2014-06-30T13:23:01.347 回答
3
Bundle in=yourBundle;
FileOutputStream fos = context.openFileOutput(localFilename, Context.MODE_PRIVATE);
Parcel p = Parcel.obtain(); //creating empty parcel object
in.writeToParcel(p, 0); //saving bundle as parcel 
fos.write(p.marshall()); //writing parcel to file
fos.flush();
fos.close();
于 2013-01-10T11:38:26.400 回答
0

这是可以帮助您将 a 转换Bundle为 a的函数JSONObject,请注意,它仅在捆绑包含ints 和Strings 时才有效

public static JSONObject bundleToJsonObject(Bundle bundle) {
    try {
        JSONObject output = new JSONObject();
        for( String key : bundle.keySet() ){
            Object object = bundle.get(key);
            if(object instanceof Integer || object instanceof String)
                    output.put(key, object);
            else
                throw new RuntimeException("only Integer and String can be extracted");
        }
        return output;
    } catch (JSONException e) {
        throw new RuntimeException(e);
    }
}

public static Bundle JsonObjectToBundle(JSONObject jsonObject) {
    try {
        Bundle bundle = new Bundle();
        Iterator<?> keys = jsonObject.keys();
        while( keys.hasNext() ){
            String key = (String)keys.next();
            Object object = jsonObject.get(key);
            if(object instanceof String)
                bundle.putString(key, (String) object);
            else if(object instanceof Integer)
                bundle.putInt(key, (Integer) object);
            else
                throw new RuntimeException("only Integer and String can be re-extracted");
        }
        return bundle;
    } catch (JSONException e) {
        throw new RuntimeException(e);
    }
}
于 2014-10-31T14:13:13.790 回答
0

你可以做这样的事情

public void write(String fileName, Bundle bundle)
    {
        File root = Environment.getExternalStorageDirectory();
        File outDir = new File(root.getAbsolutePath() + File.separator + "My Bundle");
        if (!outDir.isDirectory())
        {
            outDir.mkdir();
        }
        try
        {
            if (!outDir.isDirectory())
            {
                throw new IOException("Unable to create directory My bundle. Maybe the SD card is mounted?");


    }
        File outputFile = new File(outDir, fileName);
        writer = new BufferedWriter(new FileWriter(outputFile));
        String value=bundle.getString("key");
        writer.write(value);
        Toast.makeText(context.getApplicationContext(), "Report successfully saved to: " + outputFile.getAbsolutePath(), Toast.LENGTH_LONG).show();
        writer.close();
    } catch (IOException e)
    {
        Log.w("error", e.getMessage(), e);
        Toast.makeText(context, e.getMessage() + " Unable to write to external storage.", Toast.LENGTH_LONG).show();
    }

}

在这里,想法很简单。您将 传递Bundle给此方法,然后提取其中的任何数据(例如,在这种情况下,我们有一个带有 key 的字符串key),然后将其写入文件。

于 2013-01-10T11:37:32.203 回答
0

您无法将捆绑包保存到本地文件中。您将获得非序列化异常。可能还有其他快捷方式可以存储。阅读并构造原始对象后,并非100%放心。

于 2015-07-17T18:31:07.243 回答
0

I thing the best idea is static serializable or everything, as Bundle is iterable from keys, serialized and unserialized on another side, you can use then json, or anything. For example, if You will use the same class in server and receiver, ...

bundle->serializable_object->json->file->serializable_object->bundle

any os version guaranted working

于 2017-11-06T23:13:18.400 回答