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

相关推荐
likuolei13 分钟前
XSL-FO 软件
java·开发语言·前端·数据库
正一品程序员14 分钟前
vue项目引入GoogleMap API进行网格区域圈选
前端·javascript·vue.js
j***894620 分钟前
spring-boot-starter和spring-boot-starter-web的关联
前端
star_111225 分钟前
Jenkins+nginx部署前端vue项目
前端·vue.js·jenkins
s***117027 分钟前
Mysql convert函数、convert用法、字符串转数字、字符串转日期、类型转换函数
android·数据库·mysql
im_AMBER33 分钟前
Canvas架构手记 05 鼠标事件监听 | 原生事件封装 | ctx 结构化对象
前端·笔记·学习·架构
JIngJaneIL34 分钟前
农产品电商|基于SprinBoot+vue的农产品电商系统(源码+数据库+文档)
java·前端·数据库·vue.js·spring boot·毕设·农产品电商系统
Tongfront39 分钟前
前端通用submit方法
开发语言·前端·javascript·react
可爱又迷人的反派角色“yang”42 分钟前
LVS+Keepalived群集
linux·运维·服务器·前端·nginx·lvs
han_42 分钟前
前端高频面试题之CSS篇(二)
前端·css·面试