我正在尝试使用Parcel编写,然后读回Parcelable。由于某种原因,当我从文件读回对象时,它以null的形式返回。

public void testFoo() {
    final Foo orig = new Foo("blah blah");

    // Wrote orig to a parcel and then byte array
    final Parcel p1 = Parcel.obtain();
    p1.writeValue(orig);
    final byte[] bytes = p1.marshall();


    // Check to make sure that the byte array seems to contain a Parcelable
    assertEquals(4, bytes[0]); // Parcel.VAL_PARCELABLE


    // Unmarshall a Foo from that byte array
    final Parcel p2 = Parcel.obtain();
    p2.unmarshall(bytes, 0, bytes.length);
    final Foo result = (Foo) p2.readValue(Foo.class.getClassLoader());


    assertNotNull(result); // FAIL
    assertEquals( orig.str, result.str );
}


protected static class Foo implements Parcelable {
    protected static final Parcelable.Creator<Foo> CREATOR = new Parcelable.Creator<Foo>() {
        public Foo createFromParcel(Parcel source) {
            final Foo f = new Foo();
            f.str = (String) source.readValue(Foo.class.getClassLoader());
            return f;
        }

        public Foo[] newArray(int size) {
            throw new UnsupportedOperationException();
        }

    };


    public String str;

    public Foo() {
    }

    public Foo( String s ) {
        str = s;
    }

    public int describeContents() {
        return 0;
    }

    public void writeToParcel(Parcel dest, int ignored) {
        dest.writeValue(str);
    }


}

我想念什么?

更新:为了简化测试,我在原始示例中删除了文件的读取和写入。

最佳答案

啊,我终于找到问题了。实际上有两个。

  • CREATOR必须是公共(public)的,不 protected 。但更重要的是
  • 您必须在解码数据后调用setDataPosition(0)

  • 这是修改后的工作代码:
    public void testFoo() {
        final Foo orig = new Foo("blah blah");
        final Parcel p1 = Parcel.obtain();
        final Parcel p2 = Parcel.obtain();
        final byte[] bytes;
        final Foo result;
    
        try {
            p1.writeValue(orig);
            bytes = p1.marshall();
    
            // Check to make sure that the byte stream seems to contain a Parcelable
            assertEquals(4, bytes[0]); // Parcel.VAL_PARCELABLE
    
            p2.unmarshall(bytes, 0, bytes.length);
            p2.setDataPosition(0);
            result = (Foo) p2.readValue(Foo.class.getClassLoader());
    
        } finally {
            p1.recycle();
            p2.recycle();
        }
    
    
        assertNotNull(result);
        assertEquals( orig.str, result.str );
    
    }
    
    protected static class Foo implements Parcelable {
        public static final Parcelable.Creator<Foo> CREATOR = new Parcelable.Creator<Foo>() {
            public Foo createFromParcel(Parcel source) {
                final Foo f = new Foo();
                f.str = (String) source.readValue(Foo.class.getClassLoader());
                return f;
            }
    
            public Foo[] newArray(int size) {
                throw new UnsupportedOperationException();
            }
    
        };
    
    
        public String str;
    
        public Foo() {
        }
    
        public Foo( String s ) {
            str = s;
        }
    
        public int describeContents() {
            return 0;
        }
    
        public void writeToParcel(Parcel dest, int ignored) {
            dest.writeValue(str);
        }
    
    
    }
    

    07-27 20:51