混合开发架构|搭建Android集成Flutter3.0.1

混合框架集成Flutter

    • 创建Android原生+创建Flutter项目
    • 集成Flutter
      • [小试]原生端中显示flutter页面
    • Flutter3.0配置
    • 包管理||资源管理-加载assets
    • 偶遇报错
      • flutter_gen_runner使用问题
      • package包未使用import of dart:mirrors is not supported in the current Dart runtime
      • 找不到资源esource android:attr/lStar not found
    • 特别好用flutter知识分享网站

创建Android原生+创建Flutter项目

项目均在AS中创建,过于简单不再赘述。但在创建后需要注意并修改两个点,以避免出现创建的项目无法编译、安装问题。以我mac上的配置为例~

  • 通过查询自己当前AS版本号,引入对等gradle插件版本号。在终端通过指令flutter doctor -v即可查看。
    Android Gradle 插件版本说明->查看 | Flutter SDK下载
AndroidStudio版本 gradle插件版本 gradle版本 jdk版本 sdk版本
3.6 3.6.0 gradle-6.7-all.zip 11.0.16 30

假如gradle插件版本默认配置高于当前Android Studio版本,可能会报错并提醒你升级IDE。
This version of the Android Support plugin for IntelliJ IDEA (or Android Studio) cannot open this project, please retry with version 4.1 or newer.

  • 修改ndk配置:File-Project Structure-SDK Location选择合适的ndk版本。如果选择不到,可在Preferences-Android SDK-SDK Tools下载(Show Package Details 展示各个版本)
    混合开发架构|搭建Android集成Flutter3.0.1_第1张图片
    假如ndk默认未配置或配置高于当前所需版本,可能会报错并提醒更换并引用正确版本。
    No version of NDK matched the requested version 20.0.5594570. Versions available locally: 25.0.87751

集成Flutter

  • Android Studio 创建安卓原生项目Project,如落地在/apps目录/NativeFlutterProj项目
  • Android Studio 创建Flutter的module项目,如落地在 /apps目录/flutter_module项目 (原生项目与flutter项目等级别目录)

配置我们Android项目的Flutter module依赖,打开我们Android项目的settings.gradle添加如下代码:

...
	...  // 已存在的module

// 引入flutter
setBinding(new Binding([gradle: this]))                                 
evaluate(new File(                                                      
  settingsDir.parentFile,                                               
  'flutter_module/.android/include_flutter.groovy'                         
))

//[可选]可以在当前AS的Project下显示flutter_module以方便查看和编写Dart代码
include ':flutter_module'
project(':flutter_module').projectDir = new File('../flutter_module')   // ../flutter_module表示与当前项目同级别的引入方式                                                                  

在app/build.gradle下添加:flutter依赖

...
dependencies {
  implementation project(':flutter')
...
}

【注意】在flutter3.0下,我原生工程中未配置Java 8 的特性。会在编译安装apk时报错

  • 编译报错原因
  • 项目不支持Lambda语法,有引用第三方依赖包代码中使用了Lambda表达式。
  • Flutter的Android engine使用了Java 8 特性,在引入Flutter时需要配置项目Java 8编译选项:

Lambda表达式是JDK8的一个新特性,如果项目中有使用但没有配置JDK8编译会报错。需要在原生项目中补充

android {
  //...
  compileOptions {
    sourceCompatibility 1.8
    targetCompatibility 1.8
  }
}

混合开发架构|搭建Android集成Flutter3.0.1_第2张图片

flutter集成成功之后,可以看到有原生与flutter两者的启动入口。若集成成功,但仍未能显示flutter的入口选项——则重新打开项目即可
混合开发架构|搭建Android集成Flutter3.0.1_第3张图片

[小试]原生端中显示flutter页面

混合开发架构|搭建Android集成Flutter3.0.1_第4张图片

  • 将原生工程中MainActivity.kt中部分UI,以FlutterFragment方式显示。
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        // Native端部分UI,插入UI——FlutterFragment
        val myFlutterFragment = FlutterFragment.withNewEngine().initialRoute("main/flutter").build<FlutterFragment>()
        supportFragmentManager.beginTransaction().add(R.id.fragment_container, myFlutterFragment).commit()
    }
}
  • Flutter的Module中,由window.defaultRouteName,获取原生端初始化路由传入的参数。从而显示原生端指定要显示的内容。
import 'package:flutter/material.dart';
import 'dart:ui'; // 由它,可通过window.defaultRouteName,获取原生端初始化路由传入的参数
import 'MyHomePage.dart';


void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      // 通过初始路由显示FlutterFragment页面内容
      home: _switchPage(window.defaultRouteName),
    );
  }

  Widget _switchPage (String routePath) {
    switch (routePath) {
      case 'main/flutter':
        return const MyHomePage(title: 'Flutter Demo Home Page');
      default:
        return const MyHomePage(title: 'Flutter Demo default');
    }
  }
}

Flutter3.0配置

到官网下载Flutter 相应版本SDK,之后拷贝到你想要的指定目录并解压。然后在open ~/.bash_profile下配置,配置Flutter SDK|Flutter|JDK|Android SDK

# [官网指示,固定配置]Macintosh HD⁩ ▸ ⁨Users⁩ ▸ ⁨你的用户名 ▸ ⁨.bash_profile  
export PUB_HOSTED_URL=https://pub.flutter-io.cn
export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn
# flutter
export PATH_FLUTTER=/Users/省略目录层级/flutter-space/flutter
export PATH=$PATH_FLUTTER/bin:$PATH
# [注意]下面dart指令配置,是在终端执行flutter这个指令后,自动生成的cache/dart-sdk/...这个目录。然后才可配置,下面即可。
export PATH=$PATH_FLUTTER/bin/cache/dart-sdk/bin:$PATH
# Android-SDK
export PATH=${PATH}:/Users/省略目录层级/Library/Android/sdk/platform-tools
# jdk
export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk-11.0.16.jdk/Contents/Home
export PATH=/usr/local/bin:/usr/local/sbin:~/bin:$PATH
  • 查看jdk安装路径,查看指令/usr/libexec/java_home -V
  • 每次source ~/.bash_profile指令后,由于权限不足导致,会报:zsh compinit: insecure directories, run compaudit for list. Ignore insecure directories and continue [y] or abort compinit [n]? ——解决方案: 执行指令 compaudit 对查到的不安全目录,执行sudo chmod -R 755 zsh给对应的目录赋权限即可。

包管理||资源管理-加载assets

官方解读

个人解读,在flutter项目根目录下/pubspec.yaml中添加依赖包。原生安卓中通过gradle进行包管理,flutter也有自己的包管理工具,使用配置文件pubspec.yaml(位于项目根目录)来管理第三方依赖包。

name: flutter_android_module # 应用或包名称【注意】很重要,如果是插件在引入时需要使用该名称。【如下会遇到】
description: A new Flutter module. # 应用或包的描述、简介

version: 1.0.0+1  # 应用或包的版本号

environment:
  sdk: ">=2.17.0 <3.0.0"

dependencies: # 应用或包依赖的其他包或插件【注意:对齐、缩进和空格,有严格要求。如下~】
  flutter:
    sdk: flutter
  cupertino_icons: ^1.0.2 # ^ 表示管理并会get版本>=1.0.2的资源包。
  dio: 4.0.6 # 也可去掉 ^ 符号,目的是让项目保持原状。防止不同版本号升级导致的编译问题。【注】这个在企业工程项目中都会去掉 ^
  path_provider: 2.0.11
  # json依赖的库
  json_serializable: 6.2.0
  json_annotation: 4.5.0
  build_runner: 2.1.11  # 用于自动生成代码的一个插件 【注:比如配合flutter_gen_runner使用能有效管理assets资源】
  # 插件的名字在插件module的pubspec.yaml下的name
  player: # 这里是在引入自己创建的flutter插件
    path: player

  shared_preferences: 2.0.15
  package_info: 2.0.2 # 获取包名
  # 自动生成assets,fonts,colors 的插件
  #【注:配合build_runner使用,有效管理assets资源。即自动生成文件`lib/gen/assets.gen.dart`】
  # 如在时候时,通过 Assets.images.bgDouMine.path 即可获取下面配置的图片- asset/images/bg_dou_mine.jpeg
  flutter_gen_runner: 4.3.0 
  image_picker: 0.8.5
  get: ^4.6.5  # 状态管理插件

dev_dependencies: # 开发环境依赖的工具包(而不是flutter应用本身依赖的包)
  flutter_test:
    sdk: flutter
  flutter_lints: ^2.0.0
flutter: # flutter相关的配置选项
  uses-material-design: true

  # To add Flutter specific assets to your application, add an assets section,
  # like this:【煮:这里则是配置资源管理的资源路径】
  # 当然针对大量资源可以这样(匹配路径下所有图片资源,并结合flutter_gen_runner实现更好用功能)
  # assets:
  #    - asset/images/
  assets:
     - asset/images/play.png
     - asset/images/ic_start.png
     - asset/images/ic_pause.png
     - asset/images/bg_dou_mine.jpeg
     - asset/images/ic_dou_mine.jpeg
     - asset/videos/dongdong.flv

偶遇报错

flutter_gen_runner使用问题

使用flutter_gen_runner,在增删改部分资源后,无法再次自动生成对应的资源映射文件。原因是有旧映射文件存在导致!解决方式如下:

`// 清除之前生成的文件指令`
$flutter packages pub run build_runner clean
`// 或者直接使用指令`
$flutter packages pub run build_runner build --delete-conflicting-outputs

package包未使用import of dart:mirrors is not supported in the current Dart runtime

Android Studio终端报错提示
flutter: [ERROR:flutter/shell/common/shell.cc(93)] Dart Error: error: import of dart:mirrors is not supported in the current Dart runtime
原因是pubspec.yaml中引入库后,在dart文件中引入未使用package 导致,删除该引入包即可。

## pubspec.yaml
  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^1.0.2
  dio: 4.0.6
  path_provider: 2.0.11
  # json依赖的库
  json_serializable: 6.2.0  # 这里引入了库,删除dart中未使用的包`import 'package:json_serializable/builder.dart';`即可
  json_annotation: 4.5.0
  build_runner: 2.1.11
  # 插件的名字在插件module的pubspec.yaml下的name
  player:
    path: player

找不到资源esource android:attr/lStar not found

/Applications/Android Studio.app/Contents/gradle/gradle-5.6.4/caches/transforms-2/files-2.1/9d41ac4c761718256511ee14f21eb1fb/core-1.8.0/res/values/values.xml:104:5-113:25: AAPT: error: resource android:attr/lStar not found.
解决方案:(原因是引入的依赖的androidx.core:core-ktx版本过高导致)

  • 在native项目app/build.gradle中与android{...}同级别配置 【尝试过无效】
configurations.all {
    resolutionStrategy {
        force 'androidx.core:core-ktx:1.0.2'
    }
}
  • 将在native项目app/build.gradle中编译版本 compileSdkVersion 30配置为31,可解决。

特别好用flutter知识分享网站

点击进入查看知识分享

你可能感兴趣的:(flutter,Android,android,android,studio,gradle)