Flutter开发者进阶:接入安卓原生页面

Flutter开发者进阶:接入安卓原生页面

前言

Flutter APP 的开发过程中,有时不仅需要使用 Flutter 提供的组件,还需要使用原生的组件。

例如在对接外部 SDK 时,如果自己重新实现 SDK 的逻辑,无疑是本末倒置。

在这种情况下有两种方式可以使用:

  1. Flutter 项目转为 Flutter Module,打包为 aar ,在原生项目中引用,使用原生的方式调用 Flutter,这无疑增加了很多原生开发的工作。

  2. SDK 引入到 Flutter 中,作为一个 Flutter Plugin,建立方法通道(method channel),调用原生的方法或者页面。

本篇文章将讨论第二种方法。

将一个带有页面的原生安卓 SDK 接入 Flutter 中使用。

话不多说,直接开始。

创建Flutter Plugin

在Flutter项目的根目录执行:

shell 复制代码
flutter create --template=plugin --platforms=android my_flutter_plugin

这个会创建一个插件工程,里面已经配置好了 Flutter Plugin 的基本结构,包括 build.gradle 文件, AndroidManifest.xml 文件, pubspec.yaml 文件等。

插件工程大致的目录结构如下:

shell 复制代码
my_flutter_plugin
  |- android
  |  |- src
  |  |  |- main
  |  |  |  |- java
  |  |  |  |  |- com
  |  |  |  |  |  |- example
  |  |  |  |  |  |- my_flutter_plugin
  |  |  |  |  |  |  |- MyFlutterPlugin.java
  |  |  |  |  |- AndroidManifest.xml
  |  |  |  |- res
  |  |  |  |  |- values
  |  |  |  |  |  |- strings.xml
  |  |  |  |  |- layout
  |  |  |  |  |  |- main.xml
  |  |  |  |  |- mipmap
  |  |  |  |- build.gradle

迁入SDK

将SDK的代码文件迁入到android/src/main/java/com/example/my_flutter_plugin目录下。

包括包内的代码,注意修改包名。

融合 build.gradle 文件,尤其是 dependencies 部分。

修改 AndroidManifest.xml,清除其中的权限部分,写入到 Flutter 生成的 Android 部分里面去

将要使用的页面 Activity 注册到这里。

修改插件代码

修改MyFlutterPlugin.java文件,如下示例:

java 复制代码
// 省略 import 

// 注意这个 ActivityAware ,这是调起页面的关键,否则拿不到上下文
public class MyFlutterPlugin implements FlutterPlugin, MethodCallHandler,ActivityAware{
  private static final String TAG = "MyFlutterPlugin";
  private MethodChannel channel;
  private Activity activity;

  @Override
  public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
    channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), Tag);
    channel.setMethodCallHandler(this);
  }

  @Override
  public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
    if (call.method.equals("openNativePage")) {
      if (activity != null) {
        Intent intent = new Intent(activity, MainActivity.class);
        activity.startActivity(intent);
        result.success("Native page opened");
      } else {
        result.error("ACTIVITY_NOT_AVAILABLE", "Activity is not available", null);
      }
    } else {
      result.notImplemented();
    }
  }

  @Override
  public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
    channel.setMethodCallHandler(null);
  }

  @Override
  public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) {
    activity = binding.getActivity();
  }

  @Override
  public void onDetachedFromActivityForConfigChanges() {
    activity = null;
  }

  @Override
  public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBinding binding) {
    activity = binding.getActivity();
  }

  @Override
  public void onDetachedFromActivity() {
    activity = null;
  }
}

注册插件

Flutter 项目的 pubspec.yaml 文件中,添加如下代码:

yaml 复制代码
dependencies:
  flutter:
    sdk: flutter
  my_flutter_plugin: 
    path: ./my_flutter_plugin

重新安装依赖

shell 复制代码
flutter clean
flutter pub get

在 Flutter 中调用

dart 复制代码
 await MethodChannel("MyFlutterPlugin").invokeMethod("openNativePage");

运行 Flutter

shell 复制代码
flutter run 

现在你可以在你的 Flutter 项目中看到原生页面的调起

总结

Flutter 接入原生页面,主要通过 Flutter Plugin 的方式,通过 MethodChannel 调用原生的页面。

一般按照步骤都会调用成功,但是不排除一些特殊的情况

例如:

其它插件对 SDK 版本的要求不一致,导致启动失败,根据报错修改 SDK 版本即可。

一直报错

shell 复制代码
Unhandled Exception: MissingPluginException(No implementation found for method getPlatformVersion on channel xxx)

这个一般是通道名称不一致,或者调用页面时没有实现ActivityAware接口,导致上下文为空。

相关推荐
tedcloud1234 小时前
UI-TARS-desktop部署教程:构建AI桌面自动化系统
服务器·前端·人工智能·ui·自动化·github
UXbot7 小时前
AI原型设计工具如何支持团队协作与快速迭代
前端·交互·个人开发·ai编程·原型模式
程序员陆业聪8 小时前
两次Flutter全屏白踩坑复盘:Layout的静默失败,以及AI结对编程的认知盲区
android
ZC跨境爬虫8 小时前
跟着MDN学HTML_day_48:(Node接口)
前端·javascript·ui·html·音视频
程序员陆业聪9 小时前
Compose Strong Skipping Mode 的真相:它并不会让你的类型变 Stable
android
PieroPc10 小时前
CAMWATCH — 局域网摄像头监控系统 Fastapi + html
前端·python·html·fastapi·监控
巴巴博一11 小时前
2026 最新:Trae / Cursor 一键接入 taste-skill 完整教程(让 AI 前端告别“AI 味”)
前端·ai·ai编程
kyriewen11 小时前
半夜三点线上崩了,AI替我背了锅——用AI排错,五分钟定位三年老bug
前端·javascript·ai编程
kyriewen11 小时前
我让 AI 当了 24 小时全年无休的“毒舌考官”
前端·ci/cd·ai编程
hexu_blog11 小时前
vue+java实现图片批量压缩
java·前端·vue.js