一、Flutter与Android生态概览

各位同学,今天我们来聊聊Flutter和Android这对“欢喜冤家”。

说实话,我在移动端摸爬滚打了快十年,从早期的Eclipse+ADT,到Android Studio,再到Flutter横空出世,每一步都踩过坑。这门课的第一章,我想先带大家把整个生态看清楚——你只有知道来龙去脉,才知道怎么搭架构。

1.1 Flutter发展史:从“小试牛刀”到“企业级标配”

Flutter是Google在2015年Dart开发者峰会上首次亮相的。当时我还在做原生开发,第一反应是:“又一个跨平台框架?”说实话,那会儿React Native正火,Flutter看起来像个“后来者”。

但2018年Flutter 1.0正式发布后,我认真试了一把。嗯,真香。

为什么?因为Flutter不走寻常路——它没有用WebView,也没有桥接原生控件,而是自己用Skia引擎从头画UI。这意味着什么?说白了,你的界面在iOS和Android上长得一模一样,而且性能接近原生。

关键里程碑:

  • 2015年:Flutter预览版发布,代号“Sky”
  • 2018年:Flutter 1.0正式版,支持iOS和Android
  • 2021年:Flutter 2.0,支持Web和桌面端
  • 2023年:Flutter 3.x,Impeller渲染引擎逐步替代Skia

我个人习惯把Flutter的发展分为三个阶段:探索期(2015-2018)、成长期(2018-2021)、成熟期(2021至今)。现在你看到的Flutter,已经是一个能支撑千万级日活应用的成熟框架了。

1.2 Android原生架构回顾:别以为你忘了

在讲协同之前,我们得先回顾一下Android原生架构。你可能会想:“这我早就会了。”但我在项目中遇到过不少同学,Flutter写得很溜,一碰到原生交互就懵了。

Android原生架构,核心就三层:

层级 说明 我踩过的坑
应用层 Activity、Fragment、Service等 Activity生命周期管理不当,导致Flutter页面闪退
框架层 View体系、资源管理、ContentProvider 自定义View与Flutter渲染冲突
系统层 Linux内核、硬件抽象层(HAL) 权限申请时机不对,引发ANR

你想想看,Flutter其实是在应用层之上又加了一层自己的渲染引擎。所以协同的关键,就是让这两套体系“和平共处”。

小提示:如果你对Android原生不太熟,建议先复习一下Activity的启动模式和生命周期。我在做混合工程时,80%的Bug都出在这上面。

1.3 Flutter与原生协同的三种模式

好了,重头戏来了。Flutter和Android原生到底怎么协同?我把它总结为三种模式。这三种模式,你都得会——因为实际项目中,往往三种混着用。

模式一:Platform Channel(平台通道)

这是Flutter官方主推的方式。Flutter通过MethodChannel、EventChannel、BasicMessageChannel与原生端通信。

举个例子,你要获取设备的电池电量:

// Flutter端
static const platform = MethodChannel('samples.flutter.dev/battery');
try {
  final int result = await platform.invokeMethod('getBatteryLevel');
  print('电池电量: $result%');
} catch (e) {
  print('获取失败: $e');
}

// Android端(MainActivity.kt)
channel.setMethodCallHandler { call, result ->
  if (call.method == "getBatteryLevel") {
    val batteryLevel = getBatteryLevel()
    result.success(batteryLevel)
  } else {
    result.notImplemented()
  }
}

我曾经在一个金融项目中,用Platform Channel实现了指纹识别和Face ID的调用。注意,这里有个坑:不要在UI线程做耗时操作。我曾经见过同事直接在MethodCallHandler里做网络请求,结果界面卡死——嗯,血的教训。

避坑指南:Platform Channel是异步的,但如果你在主线程同步等待结果,Flutter的UI线程会被阻塞。我曾经因为这个原因,导致页面切换动画掉帧。解决方案:用async/await,或者把耗时操作放到后台线程。

模式二:Flutter Boost

Flutter Boost是闲鱼团队开源的一套方案。它的核心思想是:把Flutter页面当作一个“View”来管理

为什么需要它?因为在实际项目中,你不可能一下子把所有页面都改成Flutter。往往是原生页面和Flutter页面混着用。Flutter Boost帮你解决了页面路由和生命周期管理的问题。

我记得有一次,一个电商App要接入Flutter的商品详情页。如果用原生路由,Activity跳来跳去,内存管理一团糟。用了Flutter Boost后,Flutter页面就像原生Fragment一样,随用随取,随走随销毁。

Flutter Boost的核心优势:

  • 原生和Flutter页面共享路由栈
  • Flutter页面生命周期与原生同步
  • 支持页面间传参和回调

模式三:混合工程(Hybrid Engineering)

这是最灵活,也最复杂的一种模式。说白了,就是把Flutter模块作为一个Library,嵌入到原生工程中。

我建议用这种方式来组织代码:

项目根目录/
├── app/                    # 原生Android工程
│   ├── src/main/
│   └── build.gradle
├── flutter_module/         # Flutter模块
│   ├── lib/
│   ├── pubspec.yaml
│   └── build.gradle
└── settings.gradle         # 引入flutter_module

为什么推荐混合工程?因为你可以渐进式迁移。先在一个小功能上试试Flutter,没问题了再逐步扩大。我在一个日活百万的App上就是这么干的——先做了“用户反馈”页面,然后是“设置页”,最后是整个“个人中心”。

但注意,混合工程有个大坑:构建配置。Flutter和Android的Gradle版本要匹配,否则编译报错能让你怀疑人生。我曾经花了一整天,就为了对齐两个版本的依赖。

我的建议:如果你是新项目,直接用Flutter纯工程。如果是老项目改造,优先用Flutter Boost,等稳定了再考虑混合工程。别一上来就搞混合工程——我见过太多团队死在这上面。

知识体系总览

下面这张图,是我自己画的Flutter与Android协同的知识体系。你可以把它当作整个课程的地图:

Flutter与Android协同知识体系 Flutter发展史 • 2015: 预览版Sky • 2018: Flutter 1.0 • 2021: Flutter 2.0 • 2023: Flutter 3.x • Impeller渲染引擎 Android原生架构 • 应用层 - Activity/Fragment • 框架层 - View体系/资源管理 • 系统层 三种协同模式 ① Platform Channel - MethodChannel ② Flutter Boost - 页面路由管理 ③ 混合工程 核心要点 1. 理解Flutter发展史,知道它为什么能走到今天 2. 回顾Android原生架构,别把老本行丢了 3. 三种协同模式各有优劣,根据场景选择 4. 实际项目中往往三种模式混用,灵活应变 公众号:蓝海资料掘金营,微信deep3321

这张图我画了很久,就是想让你一眼看清整个知识结构。后面的章节,我们会逐一深入每个模块。别急,慢慢来。

本章小结:

  • Flutter从2015年走到今天,已经是一个成熟的跨平台方案
  • Android原生架构是协同的基础,别忽视它
  • Platform Channel适合功能调用,Flutter Boost适合页面管理,混合工程适合渐进式迁移
  • 选哪种模式,取决于你的项目现状和团队能力

好了,第一章就到这里。下一章我们会深入Platform Channel的底层原理,到时候我会带你看MethodChannel的源码——嗯,保证让你大开眼界。