Android性能优化

网络传输优化----flatBuffer

2017-07-11  本文已影响0人  田间小鹿

1.优点

优点

2.使用方法

使用方法
//包名
namespace com.xx.xx;
table Items {
    ItemId : long;
    timestemp : int;
    basic:[Basic];
}
 
table Basic{
  id:int;
  name:string;
  email:int;
  code:long;
  isVip:bool;
  count:int;
  carList:[Car];
}
 
table Car{
  id:long;
  number:long;
  describle:string;
}
 
root_type Items;
1. 工具使用

2.根据json生成和fbs 生成flatbuffer 二进制文件.bin
例如repos_json.json (有数据),对应的数据结构repos_schema.fbs ,生成repos_json.bin(二进制flatbuffer格式的)
$ ./flatc -j -b repos_schema.fbs repos_json.json

工程
public void serialize(View v){
    //==================序列化========================
    FlatBufferBuilder builder = new FlatBufferBuilder();
    int id1 = builder.createString("兰博基尼");
    //准备Car对象
    int car1 = Car.createCar(builder,10001L,88888L,id1);
    int id2 = builder.createString("奥迪A8");
    //准备Car对象
    int car2 = Car.createCar(builder,10001L,88888L,id2);
    int id3 = builder.createString("奥迪A9");
    //准备Car对象
    int car3 = Car.createCar(builder,10001L,88888L,id3);

    int[] cars = new int[3];
    cars[0]= car1;
    cars[1] = car2;
    cars[2] = car3;

    //创建Basic对象里面的Car集合
    int carList = Basic.createCarListVector(builder,cars);

    int name = builder.createString("jack");
    int email = builder.createString("jack@qq.com");
    int basic = Basic.createBasic(builder,10,name,email,100L,true,100,carList);
    int basicOffset = Items.createBasicVector(builder,new int[]{basic});
    Items.startItems(builder);
    Items.addItemId(builder,1000L);
    Items.addTimestemp(builder,2016);
    Items.addBasic(builder,basicOffset);

    int rootItems = Items.endItems(builder);
    Items.finishItemsBuffer(builder,rootItems);

    //============保存数据到文件=================
    File sdcard = Environment.getExternalStorageDirectory();
    //保存的路径
    File file = new File(sdcard,"Items.txt");
    if(file.exists()){
        file.delete();
    }
    ByteBuffer data = builder.dataBuffer();
    FileOutputStream out = null;
    FileChannel channel = null;
    try {
        out = new FileOutputStream(file);
        channel = out.getChannel();
        while(data.hasRemaining()){
            channel.write(data);
        }

    } catch (Exception e) {
        e.printStackTrace();
    }finally {
        try {
            if(out!=null){
                out.close();
            }
            if(channel!=null){
                channel.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
//===================反序列化=============================
    FileInputStream fis = null;
    FileChannel readChannel = null;
    try {
        fis = new FileInputStream(file);
        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
        readChannel = fis.getChannel();
        int readBytes = 0;
        while ((readBytes=readChannel.read(byteBuffer))!=-1){
            System.out.println("读取数据个数:"+readBytes);
        }
        //把指针回到最初的状态,准备从byteBuffer当中读取数据
        byteBuffer.flip();
        //解析出二进制为Items对象。
        Items items = Items.getRootAsItems(byteBuffer);
        //读取数据测试看看是否跟保存的一致
        Log.i(TAG,"items.id:"+items.ItemId());
        Log.i(TAG,"items.timestemp:"+items.timestemp());

        Basic basic2 = items.basic(0);
        Log.i(TAG,"basic2.name:"+basic2.name());
        Log.i(TAG,"basic2.email:"+basic2.email());

        //carList
        int length = basic2.carListLength();
        for (int i=0;i<length; i++){
            Car car = basic2.carList(i);
            Log.i(TAG,"car.number:"+car.number());
            Log.i(TAG,"car.describle:"+car.describle());
        }
    } catch (Exception e) {
        e.printStackTrace();
    }finally {
        try {
            if(readChannel!=null){
                readChannel.close();
            }
            if(fis!=null){
                fis.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

3.基本原理

原理图

FlatBuffers 保存在一个 byte 数组中,有一个“支点”指针(pivot point)以此为界,存储的内容分为两个部分:元数据和数据内容。其中元数据部分就是数据在前面,其长度等于对象中的字段数量,每个 byte 保存对应字段内容在数组中的索引(从支点位置开始计算)。

namespace com.race604.fbs;
enum FriendshipStatus: int {Friend = 1, NotFriend}
table Person {
name: string;
friendshipStatus: FriendshipStatus = Friend;
spouse: Person;
friends: [Person];
}
root_type Person;

上面的 Person 对象第一个字段是 name,其值的索引位置是 1,所以从索引位置 1 开始的字符串,就是 name 字段的值 "John"。第二个字段是 friendshipStatus,其索引值是 6,找到值为 2, 表示 NotFriend。第三个字段是 spouse,也一个 Person 对象,索引值是 12,指向的是此对象的支点位置。第四个字段是一个数组,图中表示的数组为空,所以索引值是 0。

上一篇 下一篇

猜你喜欢

热点阅读