By Qiqing
Xianyu is the first large-scale application that uses Flutter hybrid development. The pain point of developing a Xianyu client is the terrible development experience caused by compilation duration. In the Flutter-Native development mode, the Native compilation speed is slow with unbreakable challenges in module development. Since Xianyu is integrated with many middlewares of Alibaba Group, many functions cannot be called directly by Flutter. Therefore, users have to call the corresponding functions through various channels to get to Native. Xianyu currently faces the following pain points in Flutter development:
It has been a long time since this project was established. Due to the fast iteration of business and massive Native plug-ins, it is very difficult to achieve modular splitting of engineering. The following figure shows the project was initiated as modular splitting. On the business side, developers need to split and decouple all business modules, including the middleware of Alibaba Group, business encapsulation components, Native business code, Flutter bridge code, Flutter component library, and Flutter-side business code. The original intention of the project is to organize the code and provide a clean environment to run Flutter. Besides, it also helps Flutter obtain almost all the capabilities of Native. Unpacking will improve the speed and efficiency of compilation, development, and debugging. Specifically, the unpacking is to build a minimal shell project from 0 to 1. Then, it will split the basic middleware of Alibaba Group and encapsulate the business components and Flutter plug-ins. The following figure shows the overall project architecture:
The minimum shell project daily needs to be used on the single-module page. With the channel declaration and implementation embedded in it, the results will come after running the minimal shell project. On the Flutter side, the module development obtains the returned results through calling the channel of the minimum shell project in IOC. Finally, developers integrate the module development into the main project of Xianyu FWN in a pub or Git dependency mode.
Business module splitting has never been easy. It is beneficial, but the input-output ratio is unbalanced. The burden of history code is getting heavier, so the next recipient does not dare to modify the code. During the modular splitting, a new, clean engineering method was proposed at the beginning of the project, and then the middleware of Alibaba Group was split step by step. At last, Mtop, Login, FlutterBoost, and UI Plugin were split up, which took two developers three weeks to finish. The part of the result forms new business. The new interface can support the relatively rapid iterative development. The disadvantages are listed below:
How can you solve this problem? I proposed the cross-process method. On the Android side, the cross-process call has always been very a common method. The client accesses the server to obtain the results. The Flutter side and Native side operate as a client and a server. As shown in the following figure, Flutter obtains data through MethodChannel
or EventChannel
. So, there is a different way to think about it.
On the Android side, I used Android Binder to implement it and started a new app as a shell project. I implemented various plug-ins to access the main project services. Therefore, Flutter in the shell project can call the returned results, but the maintenance cost is still needed. Also, there is no corresponding implementation mechanism on the iOS side, so this method is discarded.
Android developers should be familiar with hook and plug-in technology. A new idea should be considered at the previous channel architecture from Flutter to Native. Since Native problems cannot be solved, we can solve the channel problems. Instead of implementing IPC on the Native side, we can implement IPC on the channel communication side of the Flutter side and the Native side. Based on the business understanding of the plug-in hook mechanism and IPC mechanism and my understanding of the Flutter channels, a new implementation can be achieved. The implementation method uses the socket service to implement the hook method channel and event channel for the client's method channel and event channel. Through the socket, the processed results are sent to the server to process and obtain real data from the method channel and the event channel. This is how I want it to work. The architecture is on the chart below:
The client and server operate through two mobile phones, respectively. The server runs the main project of Xianyu FWN, and the client runs a clean Flutter project. First, the client uses the Flutter-side code to find its corresponding channel. Return results if the channel is available. Otherwise, the request for the channel will be sent to the main project on the server through the socket, and the main project parses the protocol fields defined by the socket. Next, the main project initiates a channel to obtain the result and return it to the client through the socket. After the client obtains the result data from the socket, it performs the corresponding rendering.
You may wonder why it uses two phones instead of one:
The method channel code is listed below:
Future<T> invokeMethod<T>(String method, [ dynamic arguments ]) async {
assert(method != null);
final ByteData result = await binaryMessenger.send(
name,
codec.encodeMethodCall(MethodCall(method, arguments)),
);
if (result == null) {
throw MissingPluginException('No implementation found for method $method on channel $name');
}
final T typedResult = codec.decodeEnvelope(result);
return typedResult;
}
The result = = null
scenario is fixed. If it is the specified client, the server data is obtained through the socket. The major part lies in the understanding from Fish MOD:START to Fish MOD:END Code
.
Future<T> invokeMethod<T>(String method, [dynamic arguments]) async {
assert(method != null);
final ByteData result = await binaryMessenger.send(
name,
codec.encodeMethodCall(MethodCall(method, arguments)),
);
if (result == null) {
//Fish MOD:START
//throw MissingPluginException(
// 'No implementation found for method $method on channel $name');
//socket obtains the value from the server-side mobile phone.
final dynamic serverData =
await SocketClient.methodDataForClient(clientParams);
//Fish MOD:END
}
final T typedResult = codec.decodeEnvelope(result);
return typedResult;
}
Finally, the feasibility of normal data sending and receiving through MethodChannel
and EventChannel
is verified through this method, and more practices need to be carried out in specific business scenarios in the future.
Results Comparison:
Method Selection | Splitting Cost | Maintenance Cost | Runtime |
Solution One | High | High | Runtime Runlevel |
Solution Two | Zero-Cost | Zero-Cost | Runtime Runlevel (Lower) |
Solution one and solution two can eventually solve the runtime problem during compilation. However, solution one incurs a high cost for splitting and maintaining modules. Even though the runtime is reduced, the modular workload has increased a lot. Solution two can solve the splitting cost and maintenance cost perfectly, but it must be operated in a perfect environment. In addition, for some page jump logic, the operation on the client of mobile phone A may be triggered to the server of mobile phone B. Therefore, the operation is not performed on the same mobile phone. In conclusion, the second solution has some defects, and it can solve many problems. Therefore, in the follow-up implementation project of Xianyu modular splitting, the step for seeking a perfect solution won't stop.
An In-Depth Understanding of Flutter Compilation Principles and Optimizations
How Does Xianyu Improve the Technical Experience Based on Flutter?
56 posts | 4 followers
FollowAlibaba Clouder - December 22, 2020
sunqi - February 12, 2020
XianYu Tech - August 10, 2021
XianYu Tech - August 10, 2021
Alibaba Clouder - November 24, 2020
Alibaba Tech - April 24, 2020
56 posts | 4 followers
FollowExplore Web Hosting solutions that can power your personal website or empower your online business.
Learn MoreA low-code development platform to make work easier
Learn MoreExplore how our Web Hosting solutions help small and medium sized companies power their websites and online businesses.
Learn MoreHelp enterprises build high-quality, stable mobile apps
Learn MoreMore Posts by XianYu Tech