手机端实现Protocol Buffer

最近在研究push技术,里面涉及到了Protocol Buffer来进行数据的封装,在网上查了一些资料,写个帖子记录一下。


简介:

protocol buffer 是 google 的一种数据交换的格式,它独立于语言,独立于平台。google 提供了三种语言的实现:java、c++ 和 python,每一种实现都包含了相应语言的编译器以及库文件。由于它是一种二进制的格式,比使用 xml 进行数据交换快许多。可以把它用于分布式应用之间的数据通信或者异构环境下的数据交换。


安装和使用:

具体的安装和简单测试,在网上有很多,下面这个网址是我认为比较好的,也是进行了参考的。现在贡献给大家,希望大家能学到东西。

http://lichen.blog.51cto.com/697816/284015

里面详细介绍了如何下载Protocol Buffer、编译打包,并且用Java语言实现了自带的一个示例,很简单明了易懂。

下面这个网址,http://dangfan.me/2012/02/04/protocol-buffers/,简单介绍了使用Protocol Buffer时的代码书写的信息,设计部分API,使用Python语言实现了一个电话本的功能。由于Python本人不懂,所以也只是简单的看了一下,并没有太深入的研究,有会Python的可以去看看。


下面再奉献两个好的网址,一个是Google文档,一个是API文档

Protocol Buffer的Google文档:

https://developers.google.com/protocol-buffers/docs/proto?hl=zh-CN

Protocol Buffer的API文档:

https://developers.google.com/protocol-buffers/docs/reference/python/google.protobuf.message.Message-class?hl=zh-CN


好,介绍了一下Protocol Buffer(一下简称PB吧,写着太累了),下面开始我的Android实现。


先上一张图:



主要完成一个很简单的功能,在三个EditText中分别输入学号、姓名、性别,点击“提交”后保存在SDcard根目录下的一个叫做“roster.dat”文件中,然后再通过解析该文件列出所有保存过的内容。


下面介绍实现的步骤:

步骤一、书写 .proto 文件内容。

// This is a file in Proto format. Defines a Roster data-structure.
// It's my first .proto file, if you have something wanna know, please contact me.
// EMAIL: brokenrings@163.com
// CSDN_BLOG: http://my.csdn.net/carterjin



// The following two lines defines the package and classname field.
// When using protoc.exe compiling it, compilier will create a Java file using the given package structure, and named Java file
// using the given classname.
// Ex. com.carter.roster.proto.Roster.java
option java_package = "com.carter.roster.proto";
option java_outer_classname = "Roster";


message Student{
	required int32 id = 1;
	required string name = 2;
	
	enum Sex{
		MALE = 0;
		FEMALE = 1;
	}
	
	required Sex sex = 3;

}



message StudentRoster{
	repeated Student student = 1;
}

上面是.proto文件的内容,头两行(不算注释)定义了要编译成Java文件后的包名和类名,proto编译器会自动按照给定的名称生成路径和文件,例如当编译后会有“com.carter.roster.proto.Roster.java”。


步骤二、新建一个Android项目

我把步骤一写好的proto文件直接放置在了src目录下,因为这样我就可以直接进入该目录编译生成一个标准的包目录格式了。

通过cmd(或例如Total Commander等)进入到src目录下,执行"protoc --java_out=. roster.proto",会在src的com/carter/roster/proto目录下生成Roster.java。这个Java文件就是protoc通过解析proto文件自动生成的。里面的东西不用动,到时在项目里直接调用就好了。

下面粘出来出来我的生成的文件:有精力的可以看看

// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: roster.proto

package com.carter.roster.proto;

public final class Roster {
    private Roster() {
    }

    public static void registerAllExtensions(com.google.protobuf.ExtensionRegistry registry) {
    }

    public static final class Student extends com.google.protobuf.GeneratedMessage {
        // Use Student.newBuilder() to construct.
        private Student() {
            initFields();
        }

        private Student(boolean noInit) {
        }

        private static final Student defaultInstance;

        public static Student getDefaultInstance() {
            return defaultInstance;
        }

        public Student getDefaultInstanceForType() {
            return defaultInstance;
        }

        public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() {
            return com.carter.roster.proto.Roster.internal_static_Student_descriptor;
        }

        protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() {
            return com.carter.roster.proto.Roster.internal_static_Student_fieldAccessorTable;
        }

        public enum Sex implements com.google.protobuf.ProtocolMessageEnum {
            MALE(0, 0), FEMALE(1, 1), ;

            public final int getNumber() {
                return value;
            }

            public static Sex valueOf(int value) {
                switch (value) {
                    case 0:
                        return MALE;
                    case 1:
                        return FEMALE;
                    default:
                        return null;
                }
            }

            public static com.google.protobuf.Internal.EnumLiteMap<Sex> internalGetValueMap() {
                return internalValueMap;
            }

            private static com.google.protobuf.Internal.EnumLiteMap<Sex> internalValueMap = new com.google.protobuf.Internal.EnumLiteMap<Sex>() {
                public Sex findValueByNumber(int number) {
                    return Sex.valueOf(number);
                }
            };

            public final com.google.protobuf.Descriptors.EnumValueDescriptor getValueDescriptor() {
                return getDescriptor().getValues().get(index);
            }

            public final com.google.protobuf.Descriptors.EnumDescriptor getDescriptorForType() {
                return getDescriptor();
            }

            public static final com.google.protobuf.Descriptors.EnumDescriptor getDescriptor() {
                return com.carter.roster.proto.Roster.Student.getDescriptor().getEnumTypes().get(0);
            }

            private static final Sex[] VALUES = { MALE, FEMALE, };

            public static Sex valueOf(com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
                if (desc.getType() != getDescriptor()) {
                    throw new java.lang.IllegalArgumentException("EnumValueDescriptor is not for this type.");
                }
                return VALUES[desc.getIndex()];
            }

            private final int index;
            private final int value;

            private Sex(int index, int value) {
                this.index = index;
                this.value = value;
            }

            static {
                com.carter.roster.proto.Roster.getDescriptor();
            }

            // @@protoc_insertion_point(enum_scope:Student.Sex)
        }

        // required int32 id = 1;
        public static final int ID_FIELD_NUMBER = 1;
        private boolean hasId;
        private int id_ = 0;

        public boolean hasId() {
            return hasId;
        }

        public int getId() {
            return id_;
        }

        // required string name = 2;
        public static final int NAME_FIELD_NUMBER = 2;
        private boolean hasName;
        private java.lang.String name_ = "";

        public boolean hasName() {
            return hasName;
        }

        public java.lang.String getName() {
            return name_;
        }

        // required .Student.Sex sex = 3;
        public static final int SEX_FIELD_NUMBER = 3;
        private boolean hasSex;
        private com.carter.roster.proto.Roster.Student.Sex sex_;

        public boolean hasSex() {
            return hasSex;
        }

        public com.carter.roster.proto.Roster.Student.Sex getSex() {
            return sex_;
        }

        private void initFields() {
            sex_ = com.carter.roster.proto.Roster.Student.Sex.MALE;
        }

        public final boolean isInitialized() {
            if (!hasId)
                return false;
            if (!hasName)
                return false;
            if (!hasSex)
                return false;
            return true;
        }

        public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException {
            getSerializedSize();
            if (hasId()) {
                output.writeInt32(1, getId());
            }
            if (hasName()) {
                output.writeString(2, getName());
            }
            if (hasSex()) {
                output.writeEnum(3, getSex().getNumber());
            }
            getUnknownFields().writeTo(output);
        }

        private int memoizedSerializedSize = -1;

        public int getSerializedSize() {
            int size = memoizedSerializedSize;
            if (size != -1)
                return size;

            size = 0;
            if (hasId()) {
                size += com.google.protobuf.CodedOutputStream.computeInt32Size(1, getId());
            }
            if (hasName()) {
                size += com.google.protobuf.CodedOutputStream.computeStringSize(2, getName());
            }
            if (hasSex()) {
                size += com.google.protobuf.CodedOutputStream.computeEnumSize(3, getSex().getNumber());
            }
            size += getUnknownFields().getSerializedSize();
            memoizedSerializedSize = size;
            return size;
        }

        public static com.carter.roster.proto.Roster.Student parseFrom(com.google.protobuf.ByteString data)
                throws com.google.protobuf.InvalidProtocolBufferException {
            return newBuilder().mergeFrom(data).buildParsed();
        }

        public static com.carter.roster.proto.Roster.Student parseFrom(com.google.protobuf.ByteString data,
                com.google.protobuf.ExtensionRegistryLite extensionRegistry)
                throws com.google.protobuf.InvalidProtocolBufferException {
            return newBuilder().mergeFrom(data, extensionRegistry).buildParsed();
        }

        public static com.carter.roster.proto.Roster.Student parseFrom(byte[] data)
                throws com.google.protobuf.InvalidProtocolBufferException {
            return newBuilder().mergeFrom(data).buildParsed();
        }

        public static com.carter.roster.proto.Roster.Student parseFrom(byte[] data,
                com.google.protobuf.ExtensionRegistryLite extensionRegistry)
                throws com.google.protobuf.InvalidProtocolBufferException {
            return newBuilder().mergeFrom(data, extensionRegistry).buildParsed();
        }

        public static com.carter.roster.proto.Roster.Student parseFrom(java.io.InputStream input)
                throws java.io.IOException {
            return newBuilder().mergeFrom(input).buildParsed();
        }

        public static com.carter.roster.proto.Roster.Student parseFrom(java.io.InputStream input,
                com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException {
            return newBuilder().mergeFrom(input, extensionRegistry).buildParsed();
        }

        public static com.carter.roster.proto.Roster.Student parseDelimitedFrom(java.io.InputStream input)
                throws java.io.IOException {
            Builder builder = newBuilder();
            if (builder.mergeDelimitedFrom(input)) {
                return builder.buildParsed();
            } else {
                return null;
            }
        }

        public static com.carter.roster.proto.Roster.Student parseDelimitedFrom(java.io.InputStream input,
                com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException {
            Builder builder = newBuilder();
            if (builder.mergeDelimitedFrom(input, extensionRegistry)) {
                return builder.buildParsed();
            } else {
                return null;
            }
        }

        public static com.carter.roster.proto.Roster.Student parseFrom(com.google.protobuf.CodedInputStream input)
                throws java.io.IOException {
            return newBuilder().mergeFrom(input).buildParsed();
        }

        public static com.carter.roster.proto.Roster.Student parseFrom(com.google.protobuf.CodedInputStream input,
                com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException {
            return newBuilder().mergeFrom(input, extensionRegistry).buildParsed();
        }

        public static Builder newBuilder() {
            return Builder.create();
        }

        public Builder newBuilderForType() {
            return newBuilder();
        }

        public static Builder newBuilder(com.carter.roster.proto.Roster.Student prototype) {
            return newBuilder().mergeFrom(prototype);
        }

        public Builder toBuilder() {
            return newBuilder(this);
        }

        public static final class Builder extends com.google.protobuf.GeneratedMessage.Builder<Builder> {
            private com.carter.roster.proto.Roster.Student result;

            // Construct using com.carter.roster.proto.Roster.Student.newBuilder()
            private Builder() {
            }

            private static Builder create() {
                Builder builder = new Builder();
                builder.result = new com.carter.roster.proto.Roster.Student();
                return builder;
            }

            protected com.carter.roster.proto.Roster.Student internalGetResult() {
                return result;
            }

            public Builder clear() {
                if (result == null) {
                    throw new IllegalStateException("Cannot call clear() after build().");
                }
                result = new com.carter.roster.proto.Roster.Student();
                return this;
            }

            public Builder clone() {
                return create().mergeFrom(result);
            }

            public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() {
                return com.carter.roster.proto.Roster.Student.getDescriptor();
            }

            public com.carter.roster.proto.Roster.Student getDefaultInstanceForType() {
                return com.carter.roster.proto.Roster.Student.getDefaultInstance();
            }

            public boolean isInitialized() {
                return result.isInitialized();
            }

            public com.carter.roster.proto.Roster.Student build() {
                if (result != null && !isInitialized()) {
                    throw newUninitializedMessageException(result);
                }
                return buildPartial();
            }

            private com.carter.roster.proto.Roster.Student buildParsed()
                    throws com.google.protobuf.InvalidProtocolBufferException {
                if (!isInitialized()) {
                    throw newUninitializedMessageException(result).asInvalidProtocolBufferException();
                }
                return buildPartial();
            }

            public com.carter.roster.proto.Roster.Student buildPartial() {
                if (result == null) {
                    throw new IllegalStateException("build() has already been called on this Builder.");
                }
                com.carter.roster.proto.Roster.Student returnMe = result;
                result = null;
                return returnMe;
            }

            public Builder mergeFrom(com.google.protobuf.Message other) {
                if (other instanceof com.carter.roster.proto.Roster.Student) {
                    return mergeFrom((com.carter.roster.proto.Roster.Student) other);
                } else {
                    super.mergeFrom(other);
                    return this;
                }
            }

            public Builder mergeFrom(com.carter.roster.proto.Roster.Student other) {
                if (other == com.carter.roster.proto.Roster.Student.getDefaultInstance())
                    return this;
                if (other.hasId()) {
                    setId(other.getId());
                }
                if (other.hasName()) {
                    setName(other.getName());
                }
                if (other.hasSex()) {
                    setSex(other.getSex());
                }
                this.mergeUnknownFields(other.getUnknownFields());
                return this;
            }

            public Builder mergeFrom(com.google.protobuf.CodedInputStream input,
                    com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException {
                com.google.protobuf.UnknownFieldSet.Builder unknownFields = com.google.protobuf.UnknownFieldSet
                        .newBuilder(this.getUnknownFields());
                while (true) {
                    int tag = input.readTag();
                    switch (tag) {
                        case 0:
                            this.setUnknownFields(unknownFields.build());
                            return this;
                        default: {
                            if (!parseUnknownField(input, unknownFields, extensionRegistry, tag)) {
                                this.setUnknownFields(unknownFields.build());
                                return this;
                            }
                            break;
                        }
                        case 8: {
                            setId(input.readInt32());
                            break;
                        }
                        case 18: {
                            setName(input.readString());
                            break;
                        }
                        case 24: {
                            int rawValue = input.readEnum();
                            com.carter.roster.proto.Roster.Student.Sex value = com.carter.roster.proto.Roster.Student.Sex
                                    .valueOf(rawValue);
                            if (value == null) {
                                unknownFields.mergeVarintField(3, rawValue);
                            } else {
                                setSex(value);
                            }
                            break;
                        }
                    }
                }
            }

            // required int32 id = 1;
            public boolean hasId() {
                return result.hasId();
            }

            public int getId() {
                return result.getId();
            }

            public Builder setId(int value) {
                result.hasId = true;
                result.id_ = value;
                return this;
            }

            public Builder clearId() {
                result.hasId = false;
                result.id_ = 0;
                return this;
            }

            // required string name = 2;
            public boolean hasName() {
                return result.hasName();
            }

            public java.lang.String getName() {
                return result.getName();
            }

            public Builder setName(java.lang.String value) {
                if (value == null) {
                    throw new NullPointerException();
                }
                result.hasName = true;
                result.name_ = value;
                return this;
            }

            public Builder clearName() {
                result.hasName = false;
                result.name_ = getDefaultInstance().getName();
                return this;
            }

            // required .Student.Sex sex = 3;
            public boolean hasSex() {
                return result.hasSex();
            }

            public com.carter.roster.proto.Roster.Student.Sex getSex() {
                return result.getSex();
            }

            public Builder setSex(com.carter.roster.proto.Roster.Student.Sex value) {
                if (value == null) {
                    throw new NullPointerException();
                }
                result.hasSex = true;
                result.sex_ = value;
                return this;
            }

            public Builder clearSex() {
                result.hasSex = false;
                result.sex_ = com.carter.roster.proto.Roster.Student.Sex.MALE;
                return this;
            }

            // @@protoc_insertion_point(builder_scope:Student)
        }

        static {
            defaultInstance = new Student(true);
            com.carter.roster.proto.Roster.internalForceInit();
            defaultInstance.initFields();
        }

        // @@protoc_insertion_point(class_scope:Student)
    }

    public static final class StudentRoster extends com.google.protobuf.GeneratedMessage {
        // Use StudentRoster.newBuilder() to construct.
        private StudentRoster() {
            initFields();
        }

        private StudentRoster(boolean noInit) {
        }

        private static final StudentRoster defaultInstance;

        public static StudentRoster getDefaultInstance() {
            return defaultInstance;
        }

        public StudentRoster getDefaultInstanceForType() {
            return defaultInstance;
        }

        public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() {
            return com.carter.roster.proto.Roster.internal_static_StudentRoster_descriptor;
        }

        protected com.google.protobuf.GeneratedMessage.FieldAccessorTable internalGetFieldAccessorTable() {
            return com.carter.roster.proto.Roster.internal_static_StudentRoster_fieldAccessorTable;
        }

        // repeated .Student student = 1;
        public static final int STUDENT_FIELD_NUMBER = 1;
        private java.util.List<com.carter.roster.proto.Roster.Student> student_ = java.util.Collections.emptyList();

        public java.util.List<com.carter.roster.proto.Roster.Student> getStudentList() {
            return student_;
        }

        public int getStudentCount() {
            return student_.size();
        }

        public com.carter.roster.proto.Roster.Student getStudent(int index) {
            return student_.get(index);
        }

        private void initFields() {
        }

        public final boolean isInitialized() {
            for (com.carter.roster.proto.Roster.Student element : getStudentList()) {
                if (!element.isInitialized())
                    return false;
            }
            return true;
        }

        public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException {
            getSerializedSize();
            for (com.carter.roster.proto.Roster.Student element : getStudentList()) {
                output.writeMessage(1, element);
            }
            getUnknownFields().writeTo(output);
        }

        private int memoizedSerializedSize = -1;

        public int getSerializedSize() {
            int size = memoizedSerializedSize;
            if (size != -1)
                return size;

            size = 0;
            for (com.carter.roster.proto.Roster.Student element : getStudentList()) {
                size += com.google.protobuf.CodedOutputStream.computeMessageSize(1, element);
            }
            size += getUnknownFields().getSerializedSize();
            memoizedSerializedSize = size;
            return size;
        }

        public static com.carter.roster.proto.Roster.StudentRoster parseFrom(com.google.protobuf.ByteString data)
                throws com.google.protobuf.InvalidProtocolBufferException {
            return newBuilder().mergeFrom(data).buildParsed();
        }

        public static com.carter.roster.proto.Roster.StudentRoster parseFrom(com.google.protobuf.ByteString data,
                com.google.protobuf.ExtensionRegistryLite extensionRegistry)
                throws com.google.protobuf.InvalidProtocolBufferException {
            return newBuilder().mergeFrom(data, extensionRegistry).buildParsed();
        }

        public static com.carter.roster.proto.Roster.StudentRoster parseFrom(byte[] data)
                throws com.google.protobuf.InvalidProtocolBufferException {
            return newBuilder().mergeFrom(data).buildParsed();
        }

        public static com.carter.roster.proto.Roster.StudentRoster parseFrom(byte[] data,
                com.google.protobuf.ExtensionRegistryLite extensionRegistry)
                throws com.google.protobuf.InvalidProtocolBufferException {
            return newBuilder().mergeFrom(data, extensionRegistry).buildParsed();
        }

        public static com.carter.roster.proto.Roster.StudentRoster parseFrom(java.io.InputStream input)
                throws java.io.IOException {
            return newBuilder().mergeFrom(input).buildParsed();
        }

        public static com.carter.roster.proto.Roster.StudentRoster parseFrom(java.io.InputStream input,
                com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException {
            return newBuilder().mergeFrom(input, extensionRegistry).buildParsed();
        }

        public static com.carter.roster.proto.Roster.StudentRoster parseDelimitedFrom(java.io.InputStream input)
                throws java.io.IOException {
            Builder builder = newBuilder();
            if (builder.mergeDelimitedFrom(input)) {
                return builder.buildParsed();
            } else {
                return null;
            }
        }

        public static com.carter.roster.proto.Roster.StudentRoster parseDelimitedFrom(java.io.InputStream input,
                com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException {
            Builder builder = newBuilder();
            if (builder.mergeDelimitedFrom(input, extensionRegistry)) {
                return builder.buildParsed();
            } else {
                return null;
            }
        }

        public static com.carter.roster.proto.Roster.StudentRoster
                parseFrom(com.google.protobuf.CodedInputStream input) throws java.io.IOException {
            return newBuilder().mergeFrom(input).buildParsed();
        }

        public static com.carter.roster.proto.Roster.StudentRoster
                parseFrom(com.google.protobuf.CodedInputStream input,
                        com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException {
            return newBuilder().mergeFrom(input, extensionRegistry).buildParsed();
        }

        public static Builder newBuilder() {
            return Builder.create();
        }

        public Builder newBuilderForType() {
            return newBuilder();
        }

        public static Builder newBuilder(com.carter.roster.proto.Roster.StudentRoster prototype) {
            return newBuilder().mergeFrom(prototype);
        }

        public Builder toBuilder() {
            return newBuilder(this);
        }

        public static final class Builder extends com.google.protobuf.GeneratedMessage.Builder<Builder> {
            private com.carter.roster.proto.Roster.StudentRoster result;

            // Construct using com.carter.roster.proto.Roster.StudentRoster.newBuilder()
            private Builder() {
            }

            private static Builder create() {
                Builder builder = new Builder();
                builder.result = new com.carter.roster.proto.Roster.StudentRoster();
                return builder;
            }

            protected com.carter.roster.proto.Roster.StudentRoster internalGetResult() {
                return result;
            }

            public Builder clear() {
                if (result == null) {
                    throw new IllegalStateException("Cannot call clear() after build().");
                }
                result = new com.carter.roster.proto.Roster.StudentRoster();
                return this;
            }

            public Builder clone() {
                return create().mergeFrom(result);
            }

            public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() {
                return com.carter.roster.proto.Roster.StudentRoster.getDescriptor();
            }

            public com.carter.roster.proto.Roster.StudentRoster getDefaultInstanceForType() {
                return com.carter.roster.proto.Roster.StudentRoster.getDefaultInstance();
            }

            public boolean isInitialized() {
                return result.isInitialized();
            }

            public com.carter.roster.proto.Roster.StudentRoster build() {
                if (result != null && !isInitialized()) {
                    throw newUninitializedMessageException(result);
                }
                return buildPartial();
            }

            private com.carter.roster.proto.Roster.StudentRoster buildParsed()
                    throws com.google.protobuf.InvalidProtocolBufferException {
                if (!isInitialized()) {
                    throw newUninitializedMessageException(result).asInvalidProtocolBufferException();
                }
                return buildPartial();
            }

            public com.carter.roster.proto.Roster.StudentRoster buildPartial() {
                if (result == null) {
                    throw new IllegalStateException("build() has already been called on this Builder.");
                }
                if (result.student_ != java.util.Collections.EMPTY_LIST) {
                    result.student_ = java.util.Collections.unmodifiableList(result.student_);
                }
                com.carter.roster.proto.Roster.StudentRoster returnMe = result;
                result = null;
                return returnMe;
            }

            public Builder mergeFrom(com.google.protobuf.Message other) {
                if (other instanceof com.carter.roster.proto.Roster.StudentRoster) {
                    return mergeFrom((com.carter.roster.proto.Roster.StudentRoster) other);
                } else {
                    super.mergeFrom(other);
                    return this;
                }
            }

            public Builder mergeFrom(com.carter.roster.proto.Roster.StudentRoster other) {
                if (other == com.carter.roster.proto.Roster.StudentRoster.getDefaultInstance())
                    return this;
                if (!other.student_.isEmpty()) {
                    if (result.student_.isEmpty()) {
                        result.student_ = new java.util.ArrayList<com.carter.roster.proto.Roster.Student>();
                    }
                    result.student_.addAll(other.student_);
                }
                this.mergeUnknownFields(other.getUnknownFields());
                return this;
            }

            public Builder mergeFrom(com.google.protobuf.CodedInputStream input,
                    com.google.protobuf.ExtensionRegistryLite extensionRegistry) throws java.io.IOException {
                com.google.protobuf.UnknownFieldSet.Builder unknownFields = com.google.protobuf.UnknownFieldSet
                        .newBuilder(this.getUnknownFields());
                while (true) {
                    int tag = input.readTag();
                    switch (tag) {
                        case 0:
                            this.setUnknownFields(unknownFields.build());
                            return this;
                        default: {
                            if (!parseUnknownField(input, unknownFields, extensionRegistry, tag)) {
                                this.setUnknownFields(unknownFields.build());
                                return this;
                            }
                            break;
                        }
                        case 10: {
                            com.carter.roster.proto.Roster.Student.Builder subBuilder = com.carter.roster.proto.Roster.Student
                                    .newBuilder();
                            input.readMessage(subBuilder, extensionRegistry);
                            addStudent(subBuilder.buildPartial());
                            break;
                        }
                    }
                }
            }

            // repeated .Student student = 1;
            public java.util.List<com.carter.roster.proto.Roster.Student> getStudentList() {
                return java.util.Collections.unmodifiableList(result.student_);
            }

            public int getStudentCount() {
                return result.getStudentCount();
            }

            public com.carter.roster.proto.Roster.Student getStudent(int index) {
                return result.getStudent(index);
            }

            public Builder setStudent(int index, com.carter.roster.proto.Roster.Student value) {
                if (value == null) {
                    throw new NullPointerException();
                }
                result.student_.set(index, value);
                return this;
            }

            public Builder setStudent(int index, com.carter.roster.proto.Roster.Student.Builder builderForValue) {
                result.student_.set(index, builderForValue.build());
                return this;
            }

            public Builder addStudent(com.carter.roster.proto.Roster.Student value) {
                if (value == null) {
                    throw new NullPointerException();
                }
                if (result.student_.isEmpty()) {
                    result.student_ = new java.util.ArrayList<com.carter.roster.proto.Roster.Student>();
                }
                result.student_.add(value);
                return this;
            }

            public Builder addStudent(com.carter.roster.proto.Roster.Student.Builder builderForValue) {
                if (result.student_.isEmpty()) {
                    result.student_ = new java.util.ArrayList<com.carter.roster.proto.Roster.Student>();
                }
                result.student_.add(builderForValue.build());
                return this;
            }

            public Builder addAllStudent(java.lang.Iterable<? extends com.carter.roster.proto.Roster.Student> values) {
                if (result.student_.isEmpty()) {
                    result.student_ = new java.util.ArrayList<com.carter.roster.proto.Roster.Student>();
                }
                super.addAll(values, result.student_);
                return this;
            }

            public Builder clearStudent() {
                result.student_ = java.util.Collections.emptyList();
                return this;
            }

            // @@protoc_insertion_point(builder_scope:StudentRoster)
        }

        static {
            defaultInstance = new StudentRoster(true);
            com.carter.roster.proto.Roster.internalForceInit();
            defaultInstance.initFields();
        }

        // @@protoc_insertion_point(class_scope:StudentRoster)
    }

    private static com.google.protobuf.Descriptors.Descriptor internal_static_Student_descriptor;
    private static com.google.protobuf.GeneratedMessage.FieldAccessorTable internal_static_Student_fieldAccessorTable;
    private static com.google.protobuf.Descriptors.Descriptor internal_static_StudentRoster_descriptor;
    private static com.google.protobuf.GeneratedMessage.FieldAccessorTable internal_static_StudentRoster_fieldAccessorTable;

    public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() {
        return descriptor;
    }

    private static com.google.protobuf.Descriptors.FileDescriptor descriptor;
    static {
        java.lang.String[] descriptorData = { "\n\014roster.proto\"[\n\007Student\022\n\n\002id\030\001 \002(\005\022\014\n"
                + "\004name\030\002 \002(\t\022\031\n\003sex\030\003 \002(\0162\014.Student.Sex\"\033"
                + "\n\003Sex\022\010\n\004MALE\020\000\022\n\n\006FEMALE\020\001\"*\n\rStudentRo"
                + "ster\022\031\n\007student\030\001 \003(\0132\010.StudentB!\n\027com.c"
                + "arter.roster.protoB\006Roster" };
        com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
            public com.google.protobuf.ExtensionRegistry assignDescriptors(
                    com.google.protobuf.Descriptors.FileDescriptor root) {
                descriptor = root;
                internal_static_Student_descriptor = getDescriptor().getMessageTypes().get(0);
                internal_static_Student_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable(
                        internal_static_Student_descriptor, new java.lang.String[] { "Id", "Name", "Sex", },
                        com.carter.roster.proto.Roster.Student.class,
                        com.carter.roster.proto.Roster.Student.Builder.class);
                internal_static_StudentRoster_descriptor = getDescriptor().getMessageTypes().get(1);
                internal_static_StudentRoster_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable(
                        internal_static_StudentRoster_descriptor, new java.lang.String[] { "Student", },
                        com.carter.roster.proto.Roster.StudentRoster.class,
                        com.carter.roster.proto.Roster.StudentRoster.Builder.class);
                return null;
            }
        };
        com.google.protobuf.Descriptors.FileDescriptor.internalBuildGeneratedFileFrom(descriptorData,
                new com.google.protobuf.Descriptors.FileDescriptor[] {}, assigner);
    }

    public static void internalForceInit() {
    }

    // @@protoc_insertion_point(outer_class_scope)
}



步骤三、将介绍部分打包生成的jar包导入到该Android工程中,因为日后会用到。

导入成功后,我们就可以使用jar包中的API了。


**********************************************************************华丽丽的分割线******************************************************************************************************

**********************************************************************上面是配环境等,下面是开始Android程序开发******************************************************************************************************


步骤四、开发Android项目。先新建一个布局文件,有三个EditText,下面一个Button,最下面是一个ListView。顺带着写了ListView每一项的布局文件。

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
    
    <LinearLayout
        android:id="@+id/id_ll"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        >
        
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="20dp"
            android:text="学号:"
            />
        
        <EditText
            android:id="@+id/id_et"
            android:layout_width="fill_parent" 
            android:layout_height="wrap_content"
            />
        
    </LinearLayout>
    
    <LinearLayout
        android:id="@+id/name_ll"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        >
        
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="20dp"
            android:text="姓名:"
            />
        
        <EditText
            android:id="@+id/name_et"
            android:layout_width="fill_parent" 
            android:layout_height="wrap_content"
            />
        
    </LinearLayout>
    
    <LinearLayout
        android:id="@+id/sex_ll"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        >
        
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="20dp"
            android:text="性别:"
            />
        
        <EditText
            android:id="@+id/sex_et"
            android:layout_width="fill_parent" 
            android:layout_height="wrap_content"
            />
        
    </LinearLayout>
    
    <Button 
        android:id="@+id/submit_bt"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="提  交"
        android:textSize="20dp"
        android:layout_gravity="center"
        />
    
    <ListView 
        android:id="@+id/list_lv"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        />


</LinearLayout>

adapter_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="horizontal" >
    
    <TextView
        android:id="@+id/id_tv"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:layout_weight="1"
        android:text="1"
        />
    <TextView
        android:id="@+id/name_tv"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:layout_weight="1"
        android:text="1"
        />
    <TextView
        android:id="@+id/sex_tv"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:layout_weight="1"
        android:text="1"
        />
    

</LinearLayout>


步骤五、定义一个StudentInfo类,封装学号、姓名、性别三个属性。

package com.carter.roster;

public class StudentInfo {
    
    private int id;
    private String name;
    private String sex;
    
    
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    
    

}


步骤六、定义一个helper类,用来辅助程序完成有关使用PB的功能,例如通过PB写入、读取数据。完成显示和逻辑的分离。

package com.carter.roster;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import com.carter.roster.proto.Roster.Student;
import com.carter.roster.proto.Roster.Student.Sex;
import com.carter.roster.proto.Roster.StudentRoster;


/**
 * A helper that dealing with Protocol Buffer. For example, save or read student info using Protocol Buffer.</p>
 * There're two function that will be convenient to use.</p>
 * getStudentsFromFile() & saveStudentInfoFile(int, String, String)</p>
 * The first one is used to save student info into a .dat file, and the other one is used to read from it.
 */
public class InfoHelper {
    
    /**
     * File saved in SDCard.
     */
    public static final String FILE_NAME = "/mnt/sdcard/roster.dat";
    
    
    /**
     * Read student infos from the .dat file.
     * @return list the ArrayList encapsulated several StudentInfo objects. 
     */
    public static List<StudentInfo> getStudentsFromFile(){
        
        ArrayList<StudentInfo> list = new ArrayList<StudentInfo>();
        FileInputStream fis = null;
        
        try {
            fis = new FileInputStream(FILE_NAME);
            StudentRoster roster = StudentRoster.parseFrom(fis);
            int student_count = roster.getStudentCount();
            
            for(int i=0; i<student_count; i++){
                Student student = roster.getStudent(i);
                StudentInfo info = new StudentInfo();
                info.setId(student.getId());
                info.setName(student.getName());
                info.setSex(student.getSex().toString());
                list.add(info);
            }
            
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally{
            if(null!=fis){
                try {
                    fis.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
        
        return list;
    }
    
    
    
    /**
     * Save a student info using Protocol Buffer by the given infomation.
     * @param id student's id
     * @param name student's name
     * @param sex student's sex-type.MALE/FEMALE
     */
    public static void saveStudentIntoFile(int id, String name, String sex){
        FileOutputStream fos = null;
        
        StudentRoster.Builder roster = StudentRoster.newBuilder();
        Student.Builder student = Student.newBuilder();
        student.setId(id);
        student.setName(name);
        if("MALE".equalsIgnoreCase(sex)){
            student.setSex(Sex.MALE);
        }else{
            student.setSex(Sex.FEMALE);
        }
        
        roster.addStudent(student.build());
        
        try {
            fos = new FileOutputStream(FILE_NAME, true);
            roster.build().writeTo(fos);
            fos.close();
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        
    }

}

里面定义了两个方法,public static List<StudentInfo> getStudentsFromFile() 和 public static void saveStudentIntoFile(int id, String name, String sex),分别用于读取和保存。

里面的方法体都很简单,由于只是实现一下Demo,就很多情况没有考虑,如果有朋友在使用的时候发现有ANR或者FC,请自行修复吧呵呵~~~


上面就是我写的代码了,两个方法是非常重要的。由于PB自带的那个例子感觉有些复杂,我就提炼了一下自己写了一个,有想看原来的可以去\examples\目录下查看。


好吧,先写到这里。

我会把项目源码都打包传上下载页,请去CSDN下载页面下载。小弟辛苦的整理的,给个辛苦分1分哈~~~要求不多~~~

项目源码下载


  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值