In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-17 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
In this article, Xiaobian introduces in detail "how to serialize an object gracefully on Flutter" with detailed content, clear steps and proper handling of details. I hope this article "how to serialize an object gracefully on Flutter" can help you solve your doubts.
Serializing an object is a serious thing.
Serialization and deserialization of objects is a very basic requirement in our daily coding, especially the json encode/decode operation on an object. Each platform will have relevant libraries to help developers easily carry out these two operations, such as the famous GSON on the Java platform, Alibaba's open source fastJson, and so on.
On Flutter, with the help of the official JsonCodec, the encode/decode operation of json can only be performed on these three types of primitive/Map/List. For complex types, JsonCodec provides two functions for receiver/toEncodable to allow users to manually "package" and "unpack".
Obviously, the functionality provided by JsonCodec looks quite primitive, and there are a large number of complex object serialization requirements in Xianyu app. If you use this class, there will be a collective "paid serialization", and there is no guarantee of correctness.
Official recommendation
As witty as the Google official, of course he will not sit idly by. The emergence of json_serializable is an official recommendation, which uses the * buildrunner and json_ annotation libraries in Dart Build System to automatically generate fromJson/toJson function content. (the previous articles of Xingxiang have already mentioned the principle of using build_runner* to generate code.)
There have been a lot of articles on how to use json_serializable, but here are just a few steps:
Step 1 creates an entity class.
Step 2 generates code:
Let build runner generate serialization code. After the run is completed, a xxx.g.dart file appears under the folder, which is the generated file.
Step 3 proxy implementation:
Agents the fromJson and toJson operations to the classes generated above.
Why don't we use it to achieve it?
Json_serializable perfectly implements the requirements, but it also has a side that does not meet the requirements:
It is a bit tedious to use, and an additional class is introduced.
It is important that heavy use of "as" can have a significant impact on performance and the size of the final product. In fact, the use of "as" is not recommended in Xianyu's internal "flutter coding specification". (for the impact on packet size, please see the article by Mr. Sanli, and dart linter also describes the impact on the performance of as.)
In a serious way.
Based on the above analysis, it is obvious that we need a new way to solve the problems we face. Let's call it fish-serializable for the time being.
1 functions to be implemented
Let's first sort out that a serialization library needs to use:
Get all the field of serializable objects and their type information
Can construct a serializable object and assign a value to the fields in it, and the type is correct
Custom types are supported
It is best to solve the problem of generics, which will make it easier to use
It is preferable to easily switch between different serialization / deserialization modes, such as json and protobuf.
2 where is the difficulty
Flutter disables dart:mirrors, so reflection API cannot be used, so it is impossible to new an instance and scan the fields of class by reflection.
The problem of generics can be obtained because dart does not erase types, but generics still cannot be solved after nesting.
3Let's rock
Being unable to use dart:mirrors is a "hard" problem, and without reflection support, the content of the class is a black box. So we got stuck when we took the first step.
At this time, the author flashed a lot of pictures, fleeting, Wufei rabbit left, ah, no. As a language that cannot use reflection, how does it implement serialization / deserialization of objects?
After a fierce search, I found that the gods use callback functions to create class objects with macros to achieve operations such as reflection in C++.
At this time, the author also thought of the Android that used to get along day and night (now it has become flutter). The Parcelable serialization protocol in Android is a good reference, which serializes the data of the class into an intermediate storage through writeXXX APIs, and then deserializes it through readXXX APIs, which solves the first problem we mentioned above, that is, how to open the "black box" of a class.
At the same time, the Parcelable protocol also requires consumers to provide a static inner class called Creator, which is used to reflect objects or an array of objects that create such a class when deserializing. For those of us who have no reflection available, the callback function of C++ can perfectly solve the problem of object creation in deserialization.
ValueHolder
This is a base class for data transfer storage, and its internal writeXXX APIs provides the ability to expand the fields within the class, while readXXX
The fields used to assign the content reads in ValueHolder to the class.
The type argument in the readList/readMap/readSerializable function, which we use as an external object that wants to interpret the data
Mode, such as readSerializable (key: 'object'), indicates that the external want to interpret the value of key as object as T class
Type.
FishSerializable
FishSerializable is an interface,creator is a get function that returns a "callback to create a class object", and the writeTo function is used to place ValueHoder- > fields code when deserialization.
JsonSerializer
It inherits from the FishSerializer interface, implements the encode/decode function, and provides additional encodeToMap and decodeFromMap functions. JsonSerializer is similar to JsonCodec and is used to json encode/decode directly to users.
Above, we have basically completed the basic architecture design of a library on flutter that supports object serialization / deserialization operations, and the object serialization process can be simplified as follows:
Due to the existence of ValueHolder intermediate storage, we can easily switch serializers / deserializers, such as the encode/decode that the existing JsonSerializer uses to implement json, and if there is a requirement similar to protobuf, we can use ProtoBufSerializer to convert the content in ValueHolder to the format we need.
Difficulties do not exist.
1 how to match types
To support parsing of generic containers, we need logic similar to the following:
List list
= holder.readList (key: 'list')
List readList ({String key}) {
List list = _ read (key)
}
E _ flattenList (List list) {
List?.map ((dynamic item) {
/ / compare whether E belongs to a certain type, and then convert the corresponding type
});
}
In Java, you can use Class#isAssignableFrom, but in flutter, we do not find similar features provided by API. And, if you do the following test, you will find some interesting details:
Void main () {
Print ('int test')
Test (1)
Print ('\ r\ nint list test')
Test ([])
Print ('\ r\ nobject test')
Test (A ())
}
Void test (T t) {
Print (T)
Print (t.runtimeType)
Print (T = = t.runtimeType)
Print (identical (T, t.runtimeType))
}
Class A {
}
The result of the output is:
As you can see, for a container type like List, the type argument of the function cannot be compared with the runtimeType of instance. Of course, if you use t is T, you can return the correct value, but you need to construct a large number of objects. So basically, we can't do type matching and then type conversion.
2 how to parse generic nesting
The next step is how to decompose the nesting of generic containers. Consider the following scenarios:
Map listMap
ListMap = holder.readMap (key: 'listMap')
The value type you get in readMap is a List, and we don't have API to cut the type argument. So we adopted a more "stupid" and relatively practical approach. We cut the type argument with a string, such as:
List = > [List, List, int]
Then, when expanding List or Map internally, use string matching to match the type, which in current use perfectly supports the nesting of standard List and Map containers. However, container types other than standard List and Map are currently not supported.
What's more
1IDE plug-in assist
Students who have written Android Parcelable should have a deep understanding that there is a lot of "mechanical" code to be written in the Parcelable protocol, as do similar designs of fish-serializable.
In order not to be killed by the boss and the students who use the library, fish-serializable-intelij-plugin is developed to automatically generate these "mechanical" code.
2 compared with json_serializable
Fish-serializable is used in conjunction with the IDE plug-in, reducing the use of a large number of "as" operators and making the steps shorter and easier.
Compared with the code generated by json_annotation, the code generated by fish-serializable is also more readable, making it easy to modify some code implementations manually.
Fish-serializable can be perfectly compatible with other scenarios such as json_annotation by manually taking over the serialization / deserialization process.
After reading this, the article "how to serialize an object gracefully on Flutter" has been introduced. If you want to master the knowledge of this article, you still need to practice and use it to understand it. If you want to know more about related articles, please follow the industry information channel.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.