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

相关推荐
码界领航10 分钟前
【2025最新版】Chrome谷歌浏览器如何能恢复到之前的旧版本
前端·chrome
乐多_L1 小时前
使用vue3框架vue-next-admin导出表格excel(带图片)
前端·javascript·vue.js
南望无一1 小时前
React Native 0.70.x如何从本地安卓源码(ReactAndroid)构建
前端·react native
Mike_188702783511 小时前
1688代采下单API接口使用指南:实现商品采集与自动化下单
前端·python·自动化
鲨鱼辣椒️面1 小时前
HTML视口动画
前端·html
一小路一1 小时前
Go Web 开发基础:从入门到实战
服务器·前端·后端·面试·golang
堇舟1 小时前
HTML第一节
前端·html
私人珍藏库1 小时前
[Android] APK提取器(1.3.7)版本
android
纯粹要努力2 小时前
前端跨域问题及解决方案
前端·javascript·面试
小刘不知道叫啥2 小时前
React源码揭秘 | 启动入口
前端·react.js·前端框架