In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-24 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Database >
Share
Shulou(Shulou.com)05/31 Report--
This article introduces the relevant knowledge of "how to define the AIDL of Flutter". Many people will encounter such a dilemma in the operation of actual cases, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!
Flutter's product definition is a high-performance cross-platform mobile UI framework that can build Android/iOS/Web/MacOS applications with one set of code. As a UI framework, it does not have some system interfaces, and naturally it can not avoid dealing with natives. As a result, it proposes something called platform channel, which is used for flutter and native flexible exchange of data. For the convenience of description, Android is used to refer to native.
Burning goose, it only supports the transmission of some basic data types and data structures, such as bool/int/long/byte/char/String/byte [] / List/Map, etc.
So, when you want to transfer complex data, you can only package it as Map, something like this:
Await _ channel.invokeMethod ('initUser', {' name': 'Oscar',' age': 16, 'gender':' MALE', 'country':' China'})
Then in the Android layer hard code, parse out different data corresponding to different key. If you are a pure fluter project and have no plans to deal with natives in the future, or just need to interact simply, then there is nothing wrong with this approach. When your project already has a large portion of native code or you need to use third-party lib libraries that don't support flutter, it means you need to write a lot of template code like the one above. It can be seen that the efficiency is low and the maintainability is poor. At this point, you will think, it would be nice to be able to transfer the object!
And when you want to transfer the object:
Sorry, no way. I can only give you an awkward and impolite smile. Of course, it's not impossible. We can serialize objects into json objects at the top of the native layer, and then convert json to flutter objects at the flutter layer, which is also inefficient.
What is FIDL?
Anyone who has studied Android should know AIDL (Android Interface Defination Language), which is the Android interface definition language. There is an advanced method of cross-process communication in Android-Binder, but if you want to use Binder, you need to understand some Binder mechanisms and API, and you need to write a lot of template code. In order to solve this problem, Android tried to make the method of using Binder a little bit white. So AIDL is defined, telling developers that your interface file must be written as I specify, and the objects you want to transfer across processes must implement the Parcelable interface. Then, Android generates a Service.Stub class for you, secretly serializing and deserializing objects behind your back. Using this Stub class, developers can easily get started with Binder, an advanced method of cross-process communication.
FIDL (Flutter Interface Defination Language), the Flutter interface definition language, has a mission similar to AIDL, quietly doing the "dirty work" of serialization, deserialization, and automatic code generation of objects. The classes that developers see in native code can automatically generate the same classes on the Dart side as in native code through the @ FIDL annotation tag. FIDL is a mirror that maps classes from various native platforms to Dart and classes from Dart to various native platforms.
Shut up and look at things first
The first is the Java class:
Public class User {String name; int age; String country; Gender gender;} enum Gender {MALE, FEMALE}
Android side
1. Define the FIDL interface
@ FIDL public interface IUserService {void initUser (User user);}
2. Execute the command. / gradlew assembleDebug to generate IUserServiceStub classes and fidl.json files
3. Open the channel and expose the method to Flutter
FidlChannel.openChannel (getFlutterEngine () .getDartExecutor (), new IUserServiceStub () {@ Override void initUser (User user) {System.out.println (user.name + "is" + user.age + "years old!");}}
Flutter side
1. Copy the fidl.json file to the fidl directory, execute the command flutter packages pub run fidl_model, and generate the Dart interface class.
2. Bind the IUserServiceStub channel on the Android side
Await Fidl.bindChannel (IUserService.CHANNEL_NAME, _ channelConnection)
3. Call the exposed method
Await IUserService.initUser (User ())
Compile, run, and you will see Oscar is 18 years old! in Logcat.
Detailed explanation of FIDL usage
This part is a supplementary explanation for the part that is less wordy and looks at things first, and the grandfathers of the audience can skip it on their own.
The Map in the above example, generally speaking, corresponds to a class in Java:
Public class User {String name; int age; String country; Gender gender;} enum Gender {MALE, FEMALE}
If you want flutter to transfer this object without having to write the User class manually at the flutter layer, as well as writing fromJson/toJson methods, you can do this:
Android side
1. Define an interface and add the annotation @ FIDL. This annotation will tell annotationProcessor to generate some description files for interfaces and classes.
@ FIDL public interface IUserService {void initUser (User user);}
The limitations of the interface method are as follows:
Since dart does not support method overloading, methods with the same name cannot appear in the interface
Parameters only support entity classes, not callbacks
Due to the limitation of JSON decoding, Java needs a nonparametric constructor.
2. Android Studio, click sync, or execute:
. / gradlew assembleDebug
A bunch of json files are then generated, as follows:
These json files are the description files for FIDL and classes. Yes, a description file for the Gender class referenced by User is also generated.
At the same time, an implementation IUserServiceStub for IUserService is generated. That is:
Com.infiniteloop.fidl_example.IUserService.fidl.json
Com.infiniteloop.fidl_example.User.json
Com.infiniteloop.fidl_example.Gender.json
Com.infiniteloop.fidl_example.IUserServiceStub.java
Limit: only FIDL files with strong reference relationships can be generated. If the subclasses of classes strongly referenced by FIDL API are not strongly referenced by FIDL API, the corresponding description file will not be generated.
3. Open the channel in the appropriate place and expose the method to Flutter
IUserServiceStub userService = new IUserServiceStub () {@ Override void initUser (User user) {System.out.println (user.name + "is" + user.age + "years old!");} FidlChannel.openChannel (getFlutterEngine () .getDartExecutor (), userService)
4. If necessary, you can close the channel in a suitable place
FidlChannel.closeChannel (userService)
The message of the shutdown is notified to the Flutter side.
Flutter side
1. Go to your flutter project, create a fidl directory under the lib directory, copy the above json file to this directory, and then execute:
Flutter packages pub run fidl_model
The relevant dart classes can then be automatically generated in the fidl directory:
That is:
User.dart
Gender.dart
IUserService.dart
2. Bind the IUserServiceStub channel on the Android side
Bool connected = await Fidl.bindChannel (IUserService.CHANNEL_NAME, _ channelConnection)
_ channelConnection is used to track the connection status of the IUserService channel. When the channel is connected successfully, its onConnected method is called back; when the channel connection is disconnected, its onDisconnected method is called back.
3. Call the public method of the channel
If (_ channelConnection.connected) {await IUserService.initUser (User ());}
If you no longer need to use this channel, you can unbind it.
Await Fidl.unbindChannel (IUserService.CHANNEL_NAME, _ channelConnection)
Of course, FIDL does more than that.
1. FIDL API for multiple parameters
Void init (String name, Integer age, Gender gender, Conversation conversation)
2. FIDL API with return value
UserInfo getUserInfo ()
3. Support the generation of generic classes
Public class User {T country;} public class AUser {}
FIDL interface:
Void initUser (AUser user)
AUser and User classes will be generated on the dart side, and inheritance relationships will be maintained.
4. Pass enumeration
Void initEnum0 (EmptyEnum e); String initEnum1 (MessageStatus status)
5. Transfer set, Map
Void initList0 (List ids); void initList1 (Collection ids); void initList7 (Stack ids); void initList10 (BlockingQueue ids)
6. Transfer complex objects. Inheritance, abstraction, generics, enumerations, and mixed classes, one at a time.
For now, the FIDL project only implements methods on the Android side that are called from the Dart side. The following work remains to be done:
The Android side calls the method of the Dart side
Mutual calls between other platforms and Flutter methods
EventChannel,EventChannel can essentially be implemented through MethodChannel, so it's not a problem.
Solved the object transmission, these problems, are small case.
For serialization and deserialization of objects
In order to meet the customization needs of the bosses, I defined serialization / deserialization interface classes on the Java side and the Fluter side, respectively.
Java: public interface ObjectCodec {List encode (Object... Objects); T decode (byte [] input, TypeLiteral type);} Dart: abstract class ObjectCodec {dynamic decode (Uint8List input); List encode (List objects);}
Currently using JsonObjectCodec, after JSON codec, the performance will be slightly worse. Later, I also hope to work with my friends to achieve more efficient codec.
Project schedule
Most of the functions mentioned above have been implemented as long as they are related to calling methods on the Java side from the Flutter side.
I made a Demo to simulate a scenario that relies on IM (instant messaging) SDK on the Android side and needs to chat, get messages, and send messages on the Flutter side. The following is a screenshot of Demo:
1. On the home page, click the button to call the Android side method to start the chat service.
2. Chat page
Send a message to Lucy and get the chat record with Lucy
4. Call the Android side method to send N messages to Wilson and get the chat record.
This is the end of the content of "how to define the AIDL of Flutter". Thank you for reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!
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.