do you still remember? In those years we caught up with (FIDL: Flutter community AIDL)

Foreword

Hello everyone! Today, I think Amway a relatively heavy Flutter of open source projects.

Flutter product definition is a high-performance mobile UI framework cross-platform, can be constructed with a set of code while Android / iOS / Web / MacOS applications. As a UI framework , it does not have some of the system's interfaces, can not avoid dealing with natural or native. Ever since, it presents something called platform channel for flutter and native flexible exchange data. For convenience of description, it refers to a native Android generations.

do you still remember?  In those years we caught up with (FIDL: Flutter community AIDL)

Burning goose, goose fuel, fuel goose , it only supports the transmission of some of the basic data types and data structures, e.g. bool / int / long / byte / char / String / byte [] / List / Map like.

Therefore, when you want to transfer complex data points, you can only packaged Map, like this:

await _channel.invokeMethod('initUser',
    {'name': 'Oscar', 'age': 16, 'gender': 'MALE', 'country': 'China'});

Then the Android layer hard code, parsed Different data corresponding to the key. If you are going to a pure fluter project, and later there is no deal and the native, or just need a simple interaction, that this approach is understandable. And when your project has been a great part of the native code, or when you need to use a third party does not support the flutter of lib library, it means you need to write a lot of code as a template to above. Visible inefficient, and maintainability. At this point, you will want to be able to transfer objects like!

And when you want to transfer objects:

do you still remember?  In those years we caught up with (FIDL: Flutter community AIDL)

Sorry, no way, can only give you an embarrassing crisis are not polite smile. Of course, nor is not, we can target sequence into the upper primary object json, json and then turn into the object layer in the flutter flutter, the same efficiency is poor.

What is FIDL

Android learned should know AIDL (Android Interface Defination Language), namely Android Interface Definition Language. Android there is a high level of inter-process communication --Binder, but want to use Binder need to understand some of the mechanisms and API Binder, you need to write a lot of boilerplate code. Android To solve this problem, try to use white Binder way to do it. So defined AIDL, tell the developer, you must file an interface to write according to my requirements, you have to cross the object must implement the transfer process Parcelable interface. Then, Android gives you generate a Service.Stub class, secretly behind the object serialization, deserialization gave work to do. Developers using this class will be able to easily get started Stub Binder This high-level cross-process communication methods. (I made, hey)

FIDL (Flutter Interface Defination Language) interface definition language that is Flutter, its mission and AIDL very similar, quietly object serialization, deserialization, automatic code generation such "dirty work" to do. Developer seen in native code class, by @FIDL annotation tag, automatically generating the same side of the Dart and native code class. FIDL is a mirror, the various classes mapped to the native platform Dart in the Dart classes mapped onto respective native internet.

Less long-winded, look at the things

do you still remember?  In those years we caught up with (FIDL: Flutter community AIDL)

The first is the Java class:

public class User {
  String name;
  int age;
  String country;
  Gender gender;
}
enum Gender {
  MALE, FEMALE
}

Android side

1, the interface is defined FIDL

public class User {
  String name;
  int age;
  String country;
  Gender gender;
}
enum Gender {
  MALE, FEMALE
}

2, Run ./gradlew assembleDebug, IUserServiceStub generating class files and fidl.json

3, to open the channel, the method disclosed 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, the file to copy fidl.json fidl directory, Run flutter packages pub run fidl_model, interface class generated Dart

2, Android binding side passage IUserServiceStub

await Fidl.bindChannel(IUserService.CHANNEL_NAME, _channelConnection);

3, call the public method

await IUserService.initUser(User());

Compile and run, you will be able to see in Logcat the Oscar is 18 years old !.

FIDL uses detailed

This part is a little long-winded, look at what part of the additional explanations, the audience can own grandfather skipped.

In the above example of the Map, in general, will be in Java corresponds to a class:

public class User {
  String name;
  int age;
  String country;
  Gender gender;
}
enum Gender {
  MALE, FEMALE
}

If you want flutter transmission of this object without the flutter layer to manually write User class, and write fromJson / toJson method, you can do this:

Android side

1, define an interface, add annotations @FIDL. This annotation will inform annotationProcessor interfaces and generate some kind of description files.

@FIDL
public interface IUserService {
  void initUser(User user);
}

Restriction interface method as follows:

  • Since the dart does not support method overloading, so the same name can not appear in the interface method
  • Parameter only supports entity classes, do not support callbacks
  • Due to limitations of JSON decoding, Java requires no-argument constructor

2, Android Studio click sync, or execute:

./gradlew assembleDebug

Then it will have a bunch of json file as follows:

do you still remember?  In those years we caught up with (FIDL: Flutter community AIDL)

These json file is the description file FIDL and classes. Yes, it will also generate Gender class profile User referenced .

At the same time, also generates IUserService implementation IUserServiceStub. which 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

Limitations: only generate a strong relationship between the reference FIDL file, the referenced subclass FIDL strong class interfaces if the interface is not FIDL strong reference, is not generated corresponding profile.

3, the channel is opened in the right place, the method disclosed 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, the channel can be closed where appropriate

FidlChannel.closeChannel(userService);

Close to the notification message Flutter side.

Flutter side

1, the flutter into your projects, create fidl directory in the lib directory, copy the above json file to this directory and execute:

flutter packages pub run fidl_model

It can then be generated automatically based on the dart fidl directory:

do you still remember?  In those years we caught up with (FIDL: Flutter community AIDL)

which is:

  • User.dart
  • Gender.dart
  • IUserService.dart

2, Android binding side passage IUserServiceStub

bool connected = await Fidl.bindChannel(IUserService.CHANNEL_NAME, _channelConnection);

_channelConnection connection status tracking IUserService channel, when the channel connection is successful, it will callback method onConnected; when the channel is disconnected, it will onDisconnected callback method.

3, there is disclosed a method of call channels

if (_channelConnection.connected) {
  await IUserService.initUser(User());
}

</>

4. If you no longer need to use this channel, you can unbind

await Fidl.unbindChannel(IUserService.CHANNEL_NAME, _channelConnection);

Of course, FIDL function more than that

1, a plurality of parameters of the interface FIDL

void init(String name, Integer age, Gender gender, Conversation conversation);

2, with a return value of the interface FIDL

UserInfo getUserInfo();

3, support the generation of generic class

public class User<T> {
  T country;
}
public class AUser<String>{}

FIDL Interface:

void initUser(AUser user);

User will be able to generate and AUser side dart classes, inheritance can maintain.

4, enumeration transfer

void initEnum0(EmptyEnum e);
String initEnum1(MessageStatus status);

5, passing the collection, Map

void initList0(List<String> ids);
void initList1(Collection<String> ids);
void initList7(Stack<String> ids);
void initList10(BlockingQueue ids);

6, transfer complex objects. Inheritance, abstract, generics, enumerations, and mixed classes to a dozen a.

Now, FIDL project only to realize the method call from the Android side of the Dart side. There is work to do the following:

  • Android side side method calls Dart
  • Call each other platforms and Flutter methods
  • EventChannel, the EventChannel essentially be achieved by MethodChannel, no problem

Get object transmission, these problems are small case friends.

For serialization and deserialization of the objects

In order to meet the bigwigs of customization requirements that I have in Java side and Flutter side defines the serialization / de-serialization of the interface class.

Java:
public interface ObjectCodec {
    List<byte[]> encode(Object... objects);
    <T> T decode(byte[] input, TypeLiteral<T> type);
}
Dart:
abstract class ObjectCodec {
  dynamic decode(Uint8List input);
  List<Uint8List> encode(List objects);
}

Currently using JsonObjectCodec, through JSON encoding and decoding, the performance will be somewhat less. Rear and small partners also want to work together to achieve a more efficient codec.

project progress

The above-mentioned functions, as long as the method is invoked from the Java side of the associated side Flutter, most have been achieved.

I made a Demo, relies on a simulated Android side of the IM (instant messaging) SDK, chat Flutter side need to get the message, a message of the scene. The following is a Demo screenshot:

1, the home page, click on the button calls the Android side method, open the chat service

do you still remember?  In those years we caught up with (FIDL: Flutter community AIDL)

2, chat page

do you still remember?  In those years we caught up with (FIDL: Flutter community AIDL)

3, to send a message and acquires and Lucy Lucy chats

do you still remember?  In those years we caught up with (FIDL: Flutter community AIDL)

4, a method of transmitting calling side Android N Wilson messages to chat and acquires

do you still remember?  In those years we caught up with (FIDL: Flutter community AIDL)

The article is not easy, if you liked this article, or you have a lot of hope that we help, thumbs up, forward, concern  oh. Articles will be continuously updated. Absolutely dry! ! !

Guess you like

Origin blog.51cto.com/14775360/2485685