混合开发简介

使用Flutter从零开始开发App是一件轻松惬意的事情,但对于某些成熟的产品而言,完全替代弃用App的历史沉淀,全面转向Flutter是不现实的。因此使用Flutter去统一Android,iOS技术栈,把它作为现有原生App的扩展能力,通过有序推进来提升移动终端的开发效率。结果,想要在已有的原生App里嵌入一些Flutter页面主要有两种方案。一种是将另一种是将Flutter工程作为原生工程的子模块,维持固有的原生工程管理方式不变,这是原生的作为Flutter工程的子工程,由Flutter进行统一管理,这种模式称为统一管理模式。这种模式被称为三端分离模式。在Flutter框架出现早期,由于官方提供的混编方式以及资料有限,国内较早使用Flutter进行混合开发的团队大多使用的是统一管理模式。但是,通过业务转换的深度,统一管理模式的弊端也也随之显露,几乎三端(Android,iOS和Flutter)代码替换严重,相关工具链耗时也随之增长,最终导致开发效率降低。所以,后续使用Flutter进行混合开发的团队大多使用三端代码分离的模式来进行依赖治理,最终实现颤振工程的轻量级接入。除了可以轻量级接入外,三端代码分离模式还可以把颤振模块作为原生工程的子模块,从而快速地接入在完成对Flutter模块的接收后,Flutter工程可以使用Android Studio进行开发,无需再打开原生工程就可以对Dart代码和原生代码进行开发调试。使用三端分离模式进行Flutter混合开发的关键是抽离Flutter工程,将不同平台的生成标准框架化的形式进行管理,即Android使用aar,iOS使用pod。这样,Flutter的混编方案实际上就是将Flutter模块打包成aar或者pod库,然后在原生工程像引用其他第三方原生组件库那样♡Flutter模块即可。

颤振模块

在这种情况下,原生工程会依赖Flutter工程的库和资源,并且无法分开Flutter工程独立建造和运行。在混合开发中,是原生的对Flutter的依赖主要分为两部分。一个是Flutter的库和引擎,主要包含Flutter的框架库和引擎库;另一个是Flutter模块工程,即Flutter混合开发中的Flutter功能模块,主要包括扑工程的lib目录下的飞镖代码实现。对于原生工程来说,集成扑只需要在同级目录创建一个扑模块,然后构建的iOS和安卓各自的扑依赖库即可。接下来,我们只需要在原生项目的同级目录下,执行Flutter提供的内置模块命令创建Flutter模块即可,如下所示。

flutter create -t module flutter_library

执行上面的命令后,会在原始工程的同级目录下生成一个flutter_library模块工程。Flutter模块也是Flutter工程,使用Android Studio打开它,其目录如下图所示。可以看到,和普通的Flutter工程比例,Flutter模块工程也内嵌了Android工程和iOS工程,只不过偶尔情况下,Android工程和iOS工程是隐藏的。因此,对于Flutter模块工程而言,也可以像普通工程一样使用Android Studio进行开发和调试。同时,引用普通的Flutter工程,Flutter模块工程的Android工程目录下多了一个Flutter目录,此目录下的build.gradle配置就是我们建造aar时的打包配置。同样,在Flutter模块工程的iOS工程目录下也会找到一个Flutter目录,这也是Flutter模块工程既能像Flutter普通工程一样使用Android Studio进行开发调试,又能打包构建aar或pod的原因。

Android集成Flutter

在原生Android工程中集成的Flutter,原生工程对Flutter的依赖主要包括两部分,分别是Flutter库和引擎,以及Flutter工程生成的。

  • Flutter库和引擎:包含icudtl.dat,libFlutter.so以及一些类文件,最终这些文件都会被封装到Flutter.jar中。
  • Flutter工程材料:包括应用程序数据段isolate_snapshot_data,应用程序指令段isolate_snapshot_instr,虚拟机数据段vm_snapshot_data,虚拟机指令段vm_snapshot_instr以及资源文件flutter_assets。

和原生Android工程集成其他插件库的方式一样,在原生Android工程中♡Flutter模块需要先在settings.gradle中添加如下代码。

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

然后,在原生Android工程的app目录的build.gradle文件中添加如下依赖。。,其中,flutter_library为我们创建的Flutter模块。

dependencies {    implementation project(":flutter")}

然后编译并运行原生Android工程,如果没有任何错误则说明集成的Flutter模块成功。需要说明的是,由于Flutter支持的最低版本为16,所以需要将Android项目的minSdkVersion修改为16。如果出现“程序包android .support.annotation不存在”的错误,需要使用如下的命令来创建Flutter模块,因为最新版本的Android或使用androidx来管理包。

flutter create --androidx -t module flutter_library

对于Android原生工程,如果还没有升级到androidx,可以在原生Android工程上快捷键,然后依次选择【重构】→【迁移到Androidx】将Android工程升级到androidx包管理。
在原生Android工程中成功添加Flutter模块依赖后,打开原生Android工程,并在应用的入口MainActivity文件中添加如下代码。

public class MainActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        View flutterView = Flutter.createView(this, getLifecycle(), "route1");        FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);        addContentView(flutterView, layoutParams);    }}

通过Flutter提供的createView()方法,可以将Flutter页面合并成Android能够识别的视图,然后将这个视图使用Android提供的addContentView()方法添加到父窗口即可。重新运行原生Android工程,最终效果如下图可见。如果原生Android的MainActivity加载的是一个FrameLayout,那么加载只需放在Flutter页面上构建成一个片段即可,如下所示。

public class MainActivity extends AppCompatActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        FragmentTransaction ft= getSupportFragmentManager().beginTransaction();        ft.replace(R.id.fragment_container, Flutter.createFragment("Hello Flutter"));        ft.commit();    }}

除了使用Flutter模块方式集成外,还可以将Flutter模块打包成aar,然后再添加依赖。在flutter_library根目录下执行aar打包生成命令即可撤回Flutter依赖,如下所示。

flutter build apk --debug

此命令的作用是将Flutter库和引擎以及工程生成编译成一个aar包,上面命令编译的aar包是debug版本,如果需要合并发行版本,只需要把命令中的debug换成release即可。打包编译的Flutter-debug.aar位于.android / Flutter / build / outputs / aar /目录下,可以把它复制到原生Android工程的app / libs目录下,然后在原生Android工程的app目录的打包配置build.gradle中添加对它的依赖,如下所示。

dependencies {  implementation(name: 'flutter-debug', ext: 'aar')   }

然后重新编译一下项目,如果没有任何错误提示则说明Flutter模块被成功集成到Android原生工程中。

iOS集成Flutter

原生的iOS工程对颤振的依赖包含扑库和引擎,以及扑工程编译产物。其中,扑库和引擎指的是Flutter.framework等,扑工程编译产物指的是App.framework等。
在原生的iOS工程中集成的Flutter需要先配置好CocoaPods,CocoaPods是iOS的类库管理工具,用于管理第三方开源库。可见。

flutter_application_path = '../flutter_ library/load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')target 'iOSDemo' do  # Comment the next line if you don't want to use dynamic frameworks  use_frameworks!  install_all_flutter_pods(flutter_application_path)  # Pods for iOSDemo  … //省略其他脚本end '

然后,关闭原生iOS工程,并在原生iOS工程的根目录执行pod install命令安装所需的依赖包。安装完成后,使用Xcode打开iOSDemo.xcworkspace原生工程。有时情况下,Flutter是不支持Bitcode的,在Xcode中依次选择【TAGETS】→【Build Settings】→【Build Options】→【Enable Bitcode】来替换Bitcode,如下所示。图所示。如果选择使用的是Flutter早期版本,还需要添加构建阶段来支持构建Dart代码。依次选择【标签】→【构建设置】→【启用阶段】,然后单击左上角的加号新建一个“ New Run Script Phase” ”,添加如下脚本代码。

"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh" build"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh" embed

不过,最新版本的Flutter已经不需要再添加脚本了。重新运行原生iOS工程,如果没有任何错误则说明iOS成功集成了Flutter模块。除了使用Flutter模块方式外,还可以将Flutter模块打包成可以依赖的动态库,然后再使用CocoaPods添加动态库。首先,在flutter_library根目录下执行打包生成命令生成框架动态库,如下所示。

flutter build ios --debug

如果要生成发布版本,只需要把命令中的调试转换成发布即可。
然后,在原生iOS工程的根目录下创建一个名为,FletchEngine的目录,并把生成的两个框架动态库文件复制进去。不过,iOS生成的纹理要比Android多一个步骤,因为需要把Flutter工程编译生成的库手动封装成一个pod。首先,在flutter_库该目录下创建的FlutterEngine.podspec,然后添加如下脚本代码。

Pod::Spec.new do |s|  s.name             = 'FlutterEngine'  s.version          = '0.1.0'  s.summary          = 'FlutterEngine'  s.description      = <TODO: Add long description of the pod here.                       DESC  s.homepage         = 'https://github.com/xx/FlutterEngine'  s.license          = { :type => 'MIT', :file => 'LICENSE' }  s.author           = { 'xzh' => '1044817967@qq.com' }  s.source       = { :git => "", :tag => "#{s.version}" }  s.ios.deployment_target = '9.0'  s.ios.vendored_frameworks = 'App.framework', 'Flutter.framework'end

然后,执行pod lib lint命令即可拉取Flutter模块所需的组件。接下来,在原生iOS工程的Podfile文件添加生成的库即可。

target 'iOSDemo' do    pod 'FlutterEngine', :path => './'end

重新执行pod install命令安装依赖库,原生iOS工程集成Flutter模块就完成了。然后,使用Xcode打开ViewController.m文件,然后添加如下代码。

#import "ViewController.h"#import #import @interface ViewController ()@end@implementation ViewController- (void)viewDidLoad {    [super viewDidLoad];    UIButton *button = [[UIButton alloc]init];    [button setTitle:@"加载Flutter模块" forState:UIControlStateNormal];    button.backgroundColor=[UIColor redColor];    button.frame = CGRectMake(50, 50, 200, 100);    [button setTitleColor:[UIColor redColor] forState:UIControlStateHighlighted];    [button addTarget:self action:@selector(buttonPrint) forControlEvents:UIControlEventTouchUpInside];    [self.view addSubview:button];}- (void)buttonPrint{    FlutterViewController * flutterVC = [[FlutterViewController alloc]init];    [flutterVC setInitialRoute:@"defaultRoute"];    [self presentViewController:flutterVC animated:true completion:nil];}@end

在上面的代码中,我们在原生iOS中创建了一个按钮,点击按钮时就会变成到Flutter页面,最终效果如下图所示。对于FlutterViewController来说,打开ViewController.m文件,在里面添加一个加载Flutter页面的方法并添加一个按钮出现的感觉。默认情况下,Flutter为提供了两种调用方式,分别是FlutterViewController和FlutterEngine。

Flutter模块调试

根本上,Flutter的优势之一就是在开发过程中使用热重载功能来实现快速调试。替代情况下,在原生工程中集成的Flutter模块后热重载功能是无效的,需要重新运行原生工程才能看到效果。如此一来,Flutter开发的热重载优势就失去了,并且开发效率也随之降低。那么,能不能在混合项目中开启Flutter的热重载呢?答案是可以的,只需要经过如下首先,关闭原生应用,此处所说的关闭是指关闭应用的进程,而不是简单的退出应用。在Flutter模块的根目录中输入flutter attach命令,然后再次打开原生应用,就会看到连接成功的提示,如下图所示。如果,同时连接了多台设备,可以使用Flutter attach -d命令来指定连接的设备。接下来,只需要按r键即可执行热重载,按R键即可执行热重启,按d键即可断开连接。在扑工程中,我们可以直接点击调试按钮来进行代码调试,但在混合项目中,直接点击调试按钮是不起作用的。此时,可以使用Android Studio中提供的附加扑按钮来建立与flutter模块的连接,进行实现对flutter模块的代码调试,如图下图所示。上面只是完成了在原生工程中的Flutter模块,具体开发时就要遇到与Flutter模块的通信问题,路由管理问题,以及打包等。

android开发 视图联动_Flutter混合APP开发相关推荐

  1. 开发时如何使用混合App开发?

    混合APP开发(原生+H5) 混合开发(Hybrid App开发),是指在开发一款App产品的时候,为了提高效率.节省成本而利用原生与H5的开发技术的混合应用.通俗点来说,这就是网页的模式,通常由&q ...

  2. html5混合app原理,HTML5混合App开发

    内容简介 在竞争激烈的移动互联网环境下,HTML5技术一直备受关注.HTML5混合App开发与原生App开发模式之间也争议不断.相对于原生App来说,HTML5混合App开发的成本更低.周期更短,而且 ...

  3. 混合App开发,HBuilder开发移动App

    使用HBuilder开发混合App: Hbuilder:是一个在线打包工具,不需要在本地配置开发环境:直接将做好的网站,通过一些简单的操作,就能在线打包为一个App: 混合APP开发常见技术:Html ...

  4. “小程序化”,一种创新的混合App开发模式

    计算机系统集成行业作为当今比较成熟的服务业,在国内已有三十多年的发展历史. 从80年代最初的增值代理阶段发展到现如今的多平台应用和服务创新阶段,发展较为迅速. 系统集成发展至今,虽然已经取得了很大的进 ...

  5. Vue + quasar-framework进行Vue混合app开发 ─ 模拟器选择及使用(四)

    这里推荐2钟比较常用的模拟器,Genymotion和Android Studio自带的Android Virtual Device,至于喜欢用哪个就用哪个. Genymotion 需要准备下载的软件 ...

  6. 混合app开发学习笔记

    什么是混合移动App开发[重点] 苹果上的软件是如何开发出来的:使用的是 OC.或者使用Swift这门语言 安卓平台上的软件又是如何开发出来的:使用安卓相关的语言开发的,Java,安卓的控件进行开发 ...

  7. 开发缺点_成都嗨创科技:原生APP开发与混合APP开发的优缺点对比

    原生APP开发 1.开发语言: 安卓APP:Java开发语言: 苹果APP:Objective-C 或Swift 开发语言: 均为官方规定开发语言: 2.优点 1)使用体验较好,能够实现较为复杂的交互 ...

  8. 原生开发什么意思_成都APP开发:原生APP开发与Web APP开发有什么区别呢?

    智能手机上的APP应用软件对于人们来说已经成为日常工作生活当中必不可少的工具,无论是工作生活中的聊天交流,购物,饮食,出行,娱乐都会有相应的APP软件.目前常见的APP软件开发模式有两种,一种是原生A ...

  9. 在线教育培训APP开发,在线教育培训APP开发介绍

    在线教育培训APP开发,在线教育培训APP开发介绍 介绍 在线教育一直全是呈持续上升发展趋向,尤其是2020年的肺炎疫情缘故,促使在线教育的销售市场更为宽阔,在线教育app不但能为用户提供线上一对一辅 ...

最新文章

  1. 一文读懂语音识别技术原理
  2. AI 如果 “智力爆炸” ,只有普通智力的人类是蝼蚁还是宠物?
  3. python使用符号 表示单行注释-【转】Pyhton 单行、多行注释符号使用方法及规范...
  4. 在DigitalOcean玩Kubernetes(K8S)
  5. 在ASP.NET Core中获取客户端IP地址
  6. [云炬创业基础笔记]第七张创业资源测试15
  7. price change SAT trace
  8. 在此iphone上尚未受信任_电脑显示服务器上的安全数据库没有此工作站信任关系的解决方法...
  9. zabbix监控linux网卡流量,zabbix实现linux流量变化率监控
  10. (56)UART外设驱动协议(一)(第12天)
  11. PLC编程器的功能有什么功能?
  12. 数据库内外连接区别?
  13. Python机器视觉--OpenCV入门--机器视觉与OpencCV用途简介
  14. linux打开pkg文件怎么打开,linux中怎么打开tar.rar.gz文件
  15. 域外计算机无法连接远程桌面,如何开启域内计算机的远程桌面连接?
  16. 数据结构 Java数据结构 --- 二叉树
  17. 鸿蒙系统官网电脑版,华为鸿蒙pc系统
  18. 缺陷检测End-to-end training of a two-stage neural networkfor defect detection(端到端的两步神经网络的缺陷检测)
  19. eve单机版mysql_eve单机版中文下载_eve单机版下载-游迅网
  20. amcharts的使用介绍

热门文章

  1. 输出呈三角形的杨辉三角形(C语言)
  2. 目标检测——YOLOv5的学习笔记
  3. python优先队列,队列和栈
  4. 【抄】更改eclipse配置
  5. 我的开发笔记spring等常见问题
  6. 集中式 vs 分布式 版本控制
  7. Log4J基础详解及示例大全
  8. 微信小程序_简单组件使用与数据绑定
  9. teradata 数据定义
  10. 源码学习-String类