Mobile Development 13 min read

How NetEase News Integrated Flutter: A Step-by-Step Hybrid Mobile Development Guide

This article details NetEase News' practical experience of gradually integrating Flutter as a module into an existing Android/iOS codebase, covering architecture, integration methods, build modes, project management, native‑Dart communication, routing strategies, debugging, encountered issues, and stability measures.

NetEase Media Technology Team
NetEase Media Technology Team
NetEase Media Technology Team
How NetEase News Integrated Flutter: A Step-by-Step Hybrid Mobile Development Guide

Flutter Overview

Flutter is Google’s UI toolkit that enables developers to build high‑quality iOS and Android applications from a single Dart codebase. The framework consists of a Dart‑only Framework layer on top of a C++/Java/Objective‑C Engine that handles rendering, giving Flutter strong cross‑platform consistency.

Integration Approach

Two integration patterns exist:

Create a standalone Flutter application.

Add a Flutter module to an existing native Android/iOS project.

NetEase News adopted the module pattern, embedding the Flutter module into the existing Android codebase. The official guide is available at https://github.com/flutter/flutter/wiki/Add-Flutter-to-existing-apps.

Build Configurations

Debug mode uses Just‑In‑Time (JIT) compilation. The host app adds the Flutter project with compile project(':flutter') in build.gradle, enabling rapid iteration and hot‑reload.

Release mode uses Ahead‑Of‑Time (AOT) compilation. The Dart code is compiled by gen_snapshot into binary snapshot files ( vm_snapshot_data, isolate_snapshot_data, instr). The Engine is built with Ninja, producing flutter.jar that contains libflutter.so and Java bridge classes ( FlutterMain, FlutterView, etc.). The final artifact is packaged as an .aar, minimizing impact on the existing build pipeline.

Additional requirements:

minSdkVersion must be at least 16.

Android Gradle plugin version should be 3.x or higher.

Project Management

The Flutter module is added to both Android and iOS repositories as a Git submodule, with a .gitmodules file in the host repository. This allows Dart developers to work directly on the module while native teams see it as a transparent .aar dependency.

Native ↔ Dart Communication

Flutter provides three channel types for bidirectional communication:

BasicMessageChannel – exchange strings or semi‑structured data.

MethodChannel – invoke methods on the opposite side.

EventChannel – stream continuous data.

All channels rely on BinaryMessage and the FlutterNativeView implementation. NetEase News defined a unified message protocol to standardize payloads across Android, iOS, and Dart.

Third‑party plugins can be added via pubspec.yaml, and custom plugins can be created when native functionality is not covered.

Hybrid Stack and Routing

When a FlutterView is created inside an Android Activity or Fragment, multiple Flutter pages can coexist with native pages, forming a hybrid navigation stack. Two common routing strategies are:

Multiple Flutter pages share a single Activity; navigation is handled by Flutter’s internal Navigator. Native code must replicate page‑transition animations and gestures to keep the experience consistent.

Each Flutter page is hosted in its own Activity; native code controls routing. This isolates engines but increases memory usage because each Activity creates a separate engine instance.

Debugging

Flutter’s hot‑reload accelerates development. Inside the module, run flutter attach and press R (or r) after any code change to see updates instantly.

If flutter attach hangs, terminating the app process and re‑entering the Flutter page usually resolves the issue.

Issues and Solutions

SO Library Compatibility

Flutter provides native libraries for armeabi‑v7a, arm64‑v8a, x86, and x86_64. The x86 variant works only in debug mode, and there is no armeabi binary. NetEase News retained the armeabi‑v7a binaries, filtered out devices that do not support this ABI, and copied libflutter.so from the armeabi‑v7a folder to the armeabi folder during the Gradle build.

Package Size

The Flutter engine, ICU data, and snapshot files add roughly 6 MB to the APK. An initial dynamic‑download approach was prototyped but abandoned due to reliability concerns; the team now relies on the official size‑optimisation mechanisms.

Resource Sharing

Flutter assets must be declared in pubspec.yaml. Maintaining duplicate image resources for both native and Flutter sides increased bundle size and maintenance effort. A channel‑based approach to fetch native images by name was explored, but differing naming conventions across Android and iOS made it impractical, so the solution was dropped.

Stability Assurance

Gray‑scale testing on selected distribution channels.

Feature‑flag‑driven gradual rollout.

Global error handling via FlutterError.onError and runZoned, reporting to Crashlytics through a native channel.

Flutter adoption grew from 4 % to 10 % of NetEase News users, with a crash rate below 0.01 %, meeting production standards.

Future Work

iOS integration is in progress, with ongoing adjustments and optimisations. Continued improvements in the Flutter ecosystem are expected to further enhance stability and performance.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

DARTFlutteriOSAndroidHybrid Developmentmobile integration
NetEase Media Technology Team
Written by

NetEase Media Technology Team

NetEase Media Technology Team

0 followers
Reader feedback

How this landed with the community

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.