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接口,导致上下文为空。

相关推荐
sun007700几秒前
gtest 行覆盖率、函数覆盖率、分支覆盖率 . 一般这3个要达到多少?算达标
android
HjhIron3 分钟前
在浏览器中跑DeepSeek-R1:用React+WebGPU实现端侧AI推理
前端·ai编程
施棠海5 分钟前
设计稿一键变成可运行的Android页面:Pixel2XML全流程UI开发框架实战(附完整源码)
android·ui·架构
Jomurphys13 分钟前
Compose 适配 - 分辨率(密度)
android·compose
早期的虫儿有鸟吃16 分钟前
vue2--Vuex 模块化
开发语言·前端·javascript
C++、Java和Python的菜鸟30 分钟前
第5章 后端Web基础 (MySQL基础)
前端·mysql·adb
__Witheart__32 分钟前
获取产品对应文件夹
android
__Witheart__37 分钟前
版型关联的设备树查询方式
android·rockchip
门前大桥下.38 分钟前
HTML-01我的第一个网页
前端·html
浪客川43 分钟前
Android的SystemUI的启动流程简析
android·开发语言