1

我有一个实现 Parcelable 的类,但无法实现 Serializable,因为它包含一些我无法修改的基本 Android 类。

此类中的一些对象例如 Location 和 PendingIntent (它们都可以方便地 Parcelable)。

我的问题是在我的主要活动实例之间保存这些信息。

目前,我持有对此类的静态引用,效果很好。但我假设当我重新安装应用程序时,并且可能会出现更新时,我将无法相信这个静态成员不会被重新初始化。

我试图将此 Parcelable 写入文件,但使用 marshall() 并不总是有效(我收到 Binder 无法编组错误)。

我怎样才能安全地保存这些信息?

谢谢

4

3 回答 3

3

在您的示例中使用 static 会导致内存泄漏,并且不是做任何事情的好方法。

我建议仅在 3 种情况下使用静态:

  1. static final String 或 int - 常量
  2. 在内部类上(这样它们不包含对外部类的引用)
  3. 在 util 或某些情况下(如 CustomFragment.newInstance)工厂方法

问题是你为什么要坚持 PendingIntent?它的用例是用于进程间通信。

于 2013-04-05T19:37:00.327 回答
2

我使用 StateControl 类来处理对磁盘的读/写:

    public class StateControl {

    Context mContext;

    Thread worker;
    WriteObjectToFile writer;

    // StateControl Constructor 
    public StateControl(Context context) {
        mContext = context; 

        // Construct a writer to hold and save the data
        writer = new WriteObjectToFile();

        // Construct a worker thread to handle the writer
        worker = new Thread(writer);

    }// end of StateControl constructor




    // Method to save the global data
    public void saveObjectData(Object object, String key) {

        if (object == null){
            // I had a different action here
        } else {

            // Write the data to disc
            writer.setParams(new WriteParams(object, key));         
            worker.run();

        }

    }// end of saveGlobalData method


    // Method to read the Global Data
    public Object readObjectData(String key){

        Object returnData = (Object) readObjectFromFile(key);

        if (returnData == null){        
            // I had a different action here
        } else {    
            return returnData;
        }

    }// end of readGlobalData method


    // Method to erase the Global data
    public void clearObjectData(String key){

        writer.setParams(new WriteParams(null, key));       
        worker.run();

    }// end of clearGlobalData method   

    private class WriteObjectToFile implements Runnable {

        WriteParams params;

        public void setParams(WriteParams params) {
            this.params = params;
        }

        public void run() {         
            writeObjectToFile(params.getObject(), params.getFilename());                
        }

        private boolean writeObjectToFile(Object object, String filename) {

            boolean success = true;

                ObjectOutputStream objectOut = null;
                try {

                    FileOutputStream fileOut = mContext.openFileOutput(filename, Activity.MODE_PRIVATE);
                    objectOut = new ObjectOutputStream(fileOut);
                    objectOut.writeObject(object);
                    fileOut.getFD().sync();

                } catch (IOException e) {
                    success = false;
                    e.printStackTrace();
                } finally {
                    if (objectOut != null) {
                        try {
                            objectOut.close();
                        } catch (IOException e) {
                            // do nothing
                        }

                    }// end of if 
                }// End of try/catch/finally block

            return success;
        }

    }// end of writeObjectToFile method


    private Object readObjectFromFile(String filename) {

        ObjectInputStream objectIn = null;
        Object object = null;
        try {

            FileInputStream fileIn = mContext.getApplicationContext().openFileInput(filename);
            objectIn = new ObjectInputStream(fileIn);
            object = objectIn.readObject();

        } catch (FileNotFoundException e) {
            // Do nothing
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            if (objectIn != null) {
                try {
                    objectIn.close();
                } catch (IOException e) {
                    // do nowt
                }
            }
        }

        return object;
    }


    private static class WriteParams {

        Object object;
        String filename;

        public WriteParams(Object object, String filename) {
            super();
            this.object = object;
            this.filename = filename;
        }

        public Object getObject() {
            return object;
        }

        public String getFilename() {
            return filename;
        }

    }

}

然后调用公共方法来开始写/读。对于这个版本,我也在一个单独的线程中进行,但如果需要,您可以修改它。

于 2013-04-05T19:45:49.280 回答
0

粘合剂

大多数开发人员不会直接实现这个类,而是使用aidl工具来描述所需的接口,让它生成适当的Binder 子类。

来自官方文档

您是否需要将Binder对象与对象的其余部分一起存储?也许您可以在没有实例的情况下保存对象,并在恢复对象后重新Binder创建对象Binderaidl

于 2013-04-05T19:42:19.080 回答