Mobile Development
Flutter
In 2018, Google launched Flutter with a bold claim: one codebase for iOS, Android, web, desktop, and embedded - all rendering at 60fps or higher with their own rendering engine. Three companies that bet on Flutter early: Google Pay (1 billion+ transactions), BMW's connected car app (serving every BMW driver worldwide), and Alibaba's Xianyu (50 million daily active users). The key insight: by owning the rendering layer entirely, Flutter achieves pixel-perfect design consistency across every platform without compromising with platform UI conventions.
- **Google Pay** was rebuilt with Flutter to unify the iOS and Android codebases, serving 1 billion+ transactions per year. The migration reduced the mobile engineering team's maintenance burden by 35% while enabling faster feature parity across platforms.
- **BMW ConnectedDrive** uses Flutter for the in-car infotainment system and companion mobile app, running on Android Auto hardware in BMW's 2023+ vehicles and on iOS/Android phones - the same codebase targets 4 different display sizes and input methods.
- **Alibaba's Xianyu** (second-hand marketplace) serves 50 million daily active users with a Flutter frontend, chosen for its consistent performance across the wide range of Android devices common in China, where mid-range hardware must achieve the same visual quality as flagship phones.
Widget Tree and Rendering
Flutter (Google, 2018) takes a fundamentally different approach to cross-platform rendering than React Native: instead of using platform-native UI components, Flutter renders every pixel using its own graphics engine (Skia, transitioning to Impeller). The widget tree describes what to render; Flutter's framework handles layout, painting, and compositing - the result looks identical on every platform because it bypasses native UI widgets entirely.
Everything in Flutter is a widget: layout (Row, Column, Stack), styling (Padding, Container), interaction (GestureDetector), state (StatefulWidget), and primitives (Text, Image). Widgets are immutable descriptions of the UI. The framework manages three trees: Widget tree (immutable, rebuilt often), Element tree (mutable, tracks widget lifecycle), and RenderObject tree (layout and painting, expensive to rebuild).
Flutter's Impeller renderer (replacing Skia from Flutter 3.10+) pre-compiles Metal shaders on iOS at build time, eliminating the shader compilation jank that caused first-frame drops in Skia. Impeller achieves consistent 60fps from the first frame rendered, a key improvement over the old Skia-based renderer.
Why does Flutter look identical on iOS and Android while React Native apps can look different?
State Management in Flutter
Flutter's built-in state management (StatefulWidget + setState) works for local state but creates prop-drilling for shared state. The Flutter ecosystem has converged on several patterns: Provider (Google-recommended, simple dependency injection), Riverpod (Provider's successor, compile-time safe), BLoC (Business Logic Component, stream-based, popular for large teams), and GetX (minimal boilerplate, controversial).
Riverpod (Remi Rousselet, 2021) addresses Provider's limitations: providers are globally accessible without context, providers can depend on other providers, and providers are automatically disposed when no longer needed. The flutter_riverpod package adds code generation (riverpod_generator) to eliminate boilerplate and enable IDE autocompletion for provider types.
BLoC (Business Logic Component) separates business logic into a stream-based class: UI sends Events, BLoC emits States. This strict separation makes unit testing straightforward (test logic without Flutter), which is why large enterprise Flutter teams (BMW, Alibaba) prefer BLoC over simpler alternatives.
What problem does Riverpod solve compared to Provider in Flutter state management?
Dart Language for Flutter
Dart (Google, 2011) is optimized for Flutter's use case: UI programming with both AOT (release) and JIT (debug) compilation. AOT compilation produces native ARM code for release builds - no interpreter, no JIT warmup. JIT compilation enables Flutter's hot reload: change code, hot reload, see changes in <1 second while maintaining app state. This development experience is Flutter's most celebrated feature.
Dart's null safety (sound null safety since Dart 2.12, Flutter 2.0) eliminates entire classes of null pointer exceptions at compile time: variables are non-nullable by default; nullable types require explicit ? annotation. Dart's type system is sound - if the compiler says it is not null, it is not null at runtime.
Dart isolates are Dart's concurrency model: each isolate has its own memory heap and communicates via message passing (SendPort/ReceivePort). Dart's single-threaded event loop handles async I/O within an isolate; CPU-bound work that would block the UI must be moved to a separate isolate using compute() (in Flutter) or Isolate.run() (Dart 2.19+).
How does Flutter's hot reload maintain app state while applying code changes?
Platform Channels
Platform channels are Flutter's mechanism for calling native iOS (Swift/ObjC) or Android (Kotlin/Java) code. Three channel types: MethodChannel (request/response, most common), EventChannel (native-to-Flutter event streams, e.g., sensor data), and BasicMessageChannel (lower-level, custom serialization). Dart code calls invokeMethod(); the native side registers a MethodCallHandler that receives the call and returns a result.
Flutter Federated Plugins (standard since Flutter 2.0) separate the platform interface (Dart API contract), implementation packages (flutter_platform_device_android, flutter_platform_device_ios), and the app-facing package. This structure allows adding platform implementations without forking - enabling community plugins to support 5+ platforms independently.
Flutter apps cannot access platform-specific features because they use a custom rendering engine
Flutter accesses any native API via platform channels - the custom rendering engine only affects UI rendering, not platform API access
Platform channels provide a bidirectional message-passing bridge between Dart and native code; every feature accessible in Swift/Kotlin is accessible in Flutter via platform channels or existing plugins
When should EventChannel be used instead of MethodChannel for platform communication?
Key Ideas
- **Flutter** renders every pixel with Skia/Impeller (not native UI), achieving perfect visual consistency across platforms; everything is a widget (immutable description); three trees (Widget, Element, RenderObject) separate description from layout from painting.
- **State management** options: Provider/Riverpod for most apps (reactive, auto-disposing), BLoC for large teams requiring testability, GetX for minimal boilerplate - Riverpod is currently the community consensus for new projects.
- **Platform channels** give Flutter access to any native API; MethodChannel for request-response, EventChannel for continuous streams; Dart isolates handle CPU-bound work outside the UI thread.
Related Topics
Flutter connects to cross-platform development and mobile architecture:
- React Native — React Native is Flutter's primary cross-platform competitor - native UI components vs. custom renderer, JavaScript vs. Dart; the architectural tradeoffs determine which fits a given team and project
- State Management: Redux, MVI, MVVM — Flutter's BLoC pattern implements event-driven state management analogous to Redux; Riverpod implements reactive state similar to MobX - the concepts transfer directly from other frameworks
Вопросы для размышления
- A fintech app must display the platform-native payment sheet (Apple Pay / Google Pay) embedded within a custom Flutter UI. What approach would be used to integrate this native component, and what are the constraints?
- Compare BLoC and Riverpod state management for a team of 15 Flutter engineers building a complex e-commerce app. What factors determine the better choice?
- Flutter's custom renderer means platform accessibility APIs (VoiceOver, TalkBack) are not automatic. How does Flutter implement accessibility, and what are the developer's responsibilities?