Mobile Development 9 min read

Modularization and Cross‑Process Communication Strategies for Xianyu's Flutter Application

Xianyu tackles Flutter’s slow hybrid compilation and native‑module integration pain by introducing a minimal‑shell modular architecture and a two‑phone cross‑process setup that falls back from MethodChannel to socket communication, speeding builds, isolating components, and improving data consistency while adding maintenance and device constraints.

Xianyu Technology
Xianyu Technology
Xianyu Technology
Modularization and Cross‑Process Communication Strategies for Xianyu's Flutter Application

Xianyu is the first large‑scale app to adopt Flutter mixed development, but it faces serious pain points, especially long compilation times and integration complexity with native modules.

Key issues:

Flutter side hybrid compilation is slow: Android first‑time compile >10 min, iOS >20 min.

Data inconsistency between iOS and Android when returning to Flutter.

Low development efficiency for integrated modules; performance data for single‑module pages cannot be expanded.

Solution 1 – Modular Development: The project creates a minimal shell ("minimal shell engine") that declares and implements required channels. Flutter modules call these channels via IOC, and the modules are later integrated into the main Xianyu FW‑N project as Pub or Git dependencies. This approach isolates business components, middleware, native code, and Flutter plugins into separate modules, improving code organization and allowing faster iteration for new features.

Solution 2 – Cross‑Process Development: To avoid the heavy cost of maintaining a minimal shell on a single device, a two‑phone architecture is proposed. One phone runs the Flutter client, the other runs the native server (the main Xianyu FW‑N engine). The client first tries a local MethodChannel; if unavailable, it requests the result via a socket to the server, which then invokes the native channel and returns the data. This leverages Android Binder‑style IPC on the server side and a socket bridge on the client side.

Sample MethodChannel implementation (original code retained):

Future
invokeMethod
(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
    //socket request to server for data
    final dynamic serverData = await SocketClient.methodDataForClient(clientParams);
    //Fish MOD:END
    throw MissingPluginException('No implementation found for method $method on channel $name');
  }
  final T typedResult = codec.decodeEnvelope(result);
  return typedResult;
}

The modification replaces the MissingPluginException with a socket‑based fallback, enabling the client to obtain data from the server when the native channel is absent.

Verification showed that MethodChannel and EventChannel data can be successfully transmitted using this approach. While Solution 1 reduces compile time, it increases module maintenance cost. Solution 2 solves both compile‑time and modularization costs but requires two devices and introduces operational constraints. Future work will explore more streamlined architectures for Xianyu's modular Flutter migration.

FlutteriOSModularizationAndroidMethodChannelCross-Process
Xianyu Technology
Written by

Xianyu Technology

Official account of the Xianyu technology team

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.