Apply flatbuffer in Android

Chris Chen
3 min readNov 14, 2019
Image source from here

The performance/memory tuning is a huge topic in engineer world. In order to delight our user to make a good UX. We always need to think about how to improve our application no matter in memory management and performance. One of thing we can do is how to accelerate the network request call. There are some data format for communication between client and server: such as xml, JSON in http and gRPC in http/2. In this article I want to introduce alternative way — FlatBuffer.

Why flatbuffer?

FlatBuffer is an efficient cross platform serialization library. It will flat our data in a binary buffer which size is less than the traditional JSON format. Here are some reasons why we should adopt flutter in our android project.

  • Access to serialized data without parsing/unpacking
  • Memory efficiency and speed
  • Flexible
  • Tiny code footprint
  • Strongly typed
  • Convenient to use
  • Cross platform code with no dependencie

Step by Step

Here are some step for how you apply flatbuffer to your app.

1. need to install the cmake

> brew install cmake

2. setup the flatbuffer

Clone flatbuffer project via github

Then we need to compile

> cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release

under project and run make

> make
[ 36%] Built target flatc
[ 48%] Built target flatsampletext[ 70%] Built target flattests[ 75%] Built target flatsamplebinary[ 88%] Built target flatsamplebfbs[ 91%] Built target flathash[100%] Built target flatbuffers

or do alternatively simply way

> brew install flatbuffers

can add alias for flatc CLI (Optional)

#flatbuffer CLIalias flatc=your_local_repo_path/flatbuffers/flatc

Then can use flatc

3. Copy google flatbuffer package to your project

4. Write a schema

Can refer to here. This only write once can apply to all platform.

Let’s say we have a schema in JSON like below:

{
"name": "Charles",
"bloodVolume": 2,
"speed": 110.5,
"canFly": false,
"bag": {
"name": "small bag",
"capacity": 100
},
"weapons": [
{
"name": "axe",
"damage": 100
},
{
"name": "gun",
"damage": 500
}
],
"accessories": [
"T-shirt",
"pants"
]
}

So the Person.fbs will look like:

namespace your.target.package;

table Person {
name: string;
bloodVolume: int;
speed: double;
canFly: bool;
bag: Bag;
weapons: [Weapon];
accessories: [string];
}

table Weapon {
name: string;
damage: int;
}

table Bag {
name: string;
capacity: short;
}

root_type Person;

Then we can generate Java classes for tables/structs

//be careful your path
> flatc -o app/src/main/java/ --java Person.fbs

Then everything done.

Testing

If we want to test on this only in app. We can create personinjson.json in res/raw.

Then we can generate the json in binary file.

//be careful your path
> flatc -b Person.fbs app/src/main/res/raw/personinjson.json

Then we can compare the JSON file and binary. The binary size is less than JSON file around 30% in general case.

Limitation

If you interesting how flatbuffer works. It is uses offset to read the memory address of the value. You can check the source file which generate by Person.fbs file.

Generate by flatc

So there are some limitation for flatbuffer.

  • Flatbuffer is unlike JSON. The attribute is case-insensitive
  • Flatbuffer is unlike JSON. It cannot extract structure like map (key, value pair)
  • Default values only support for int, bool, float, double rather than string
  • Not easy to debug since the response is in binary
  • Only suitable for infrequently changed API or you need complicate attribute version control.
  • Only show exception in runtime when access the wrong type of the value.

Conclusion

JSON: 319 Bytes
Flatbuffer: 200 Bytes
com.chris.flatbuffer_example D/MainActivity: json load time : 46 mscom.chris.flatbuffer_example D/MainActivity: flatbuffer load time1: 2 ms

Let’s see the final result. The Flatbuffer flie size is less than JSON file. As for deserialization, flatbuffer is more efficiency than Gson. For more detailed information can check benchmark. Facebook also adopt this solution to improve the app performance. They wrote an article here. I also put an example in my github. Hope you like it. :)

--

--