flutter可能是未来跨平台开发的又一技术框架,那么对于一个app,我们不可能完全用flutter来开发,那么就意味着我们需要在已有的Android和iOS代码中去集成flutter。目前这一技术还处于预览状态,并且还要切换flutter的channel为mater分支。如下,官方原话:
  
  那么我们在集成之前需要查看现在flutter处于什么渠道:
  
  我的是处于master分支,如果你以前没改过的话,应该是beta分支,那么可以执行:
  
  flutter channel master
  
  进行切换。
  
  下面正式开始集成Android和iOS。
  
  Android
  
  首先用Android studio创建一个Android工程,步骤不做介绍了。然后在Android工程的根目录执行一下命令:
  
  flutter create -t module my_flutter
  
  来创建一个flutter的module,成功之后,目录结构如下:
  
  接着我们来修改一下Android功能里的gradle文件:
  
  首先是app的setting.gradle文件,添加如下:
  
  include ':app'
  
  setBinding(new Binding([gradle: this]))
  
  evaluate(new File(
  
  settingsDir.parentFile,
  
  'my_flutter/.android/include_flutter.groovy'
  
  ))
  
  目的就是去加载指定目录的include_flutter.groovy文件,那么我们查看一下这个文件:
  
  // Generated file. Do not edit.
  
  def scriptFile = getClass().protectionDomain.codeSource.location.path
  
  def flutterProjectRoot = new File(scriptFile).parentFile.parentFile
  
  gradle.include ':flutter'
  
  gradle.project(':flutter').projectDir = new File(flutterProjectRoot, '.android/Flutter')
  
  def plugins = new Properties()
  
  def pluginsFile = new File(flutterProjectRoot, '.flutter-plugins')
  
  if (pluginsFile.exists()) {
  
  pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
  
  }
  
  plugins.each { name, path ->
  
  def pluginDirectory = flutterProjectRoot.toPath().resolve(path).resolve('android').toFile()
  
  gradle.include ":$name"
  
  gradle.project(":$name").projectDir = pluginDirectory
  
  }
  
  gradle.getGradle().projectsLoaded { g ->
  
  g.rootProject.afterEvaluate { p ->
  
  p.subprojects { sp ->
  
  if (sp.name != 'flutter') {
  
  sp.evaluationDependsOn(':flutter')
  
  }
  
  }
  
  }
  
  }
  
  其中最重要的一段代码,就是include ':flutter',意思就是flutter这个module要参与编译。
  
  接着在app层级(不是project层)的build.gradle文件中添加依赖:
  
  dependencies {
  
  implementation project(':flutter')
  
  :
  
  }
  
  OK配置阶段结束,我们开始先写Android代码,在activity中添加一个button,当我们点击它时,将加载flutter布局,代码如下:
  
  public class MainActivity extends AppCompatActivity {
  
  private TextView button;
  
  @Override
  
  protected void onCreate(Bundle savedInstanceState) {
  
  super.onCreate(savedInstanceState);
  
  setContentView(R.layout.activity_main);
  
  button = findViewById(R.id.button);
  
  button.setOnClickListener(new View.OnClickListener() {
  
  @Override
  
  public void onClick(View view) {
  
  FragmentTransaction tx = getSupportFragmentManager().beginTransaction();
  
  tx.replace(R.id.container, Flutter.createFragment("route1"));
  
  tx.commit();
  
  // View flutterView = Flutter.createView(MainActivity.this,getLifecycle(),"route1");
  
  // FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(100,100);
  
  // params.leftMargin = 100;
  
  // params.topMargin = 200;
  
  // addContentView(flutterView,params);
  
  }
  
  });
  
  }
  
  }
  
  这里有两种实现方式,一种是使用fragment,一种是使用FlutterView。代码中的route1字符串则是flutter代码中定义的,接下来就开始写flutter代码:
  
  import 'dart:ui';
  
  import 'package:flutter/material.dart';
  
  void main() => runApp(_widgetForRoute(window.defaultRouteName));
  
  Widget _widgetForRoute(String route) {
  
  switch (route) {
  
  case 'route1':
  
  return SomeWidget();
  
  case 'route2':
  
  return SomeWidget();
  
  default:
  
  return Center(
  
  child: Text('Unknown route: $route', textDirection: TextDirection.ltr),
  
  );
  
  }
  
  }
  
  class SomeWidget extends StatelessWidget{
  
  @override
  
  Widget build(BuildContext context) {
  
  // TODO: implement build
  
  return Container www.furong157.com (
  
  width: 100,
  
  height: 100,
  
  color: Color(www.michenggw.com xFF00FF00),
  
  child: Center(
  
  child: Text("hello",textDirection: TextDirection.ltr,),
  
  ),
  
  );
  
  }
  
  }
  
  这里可以看到对rout1的定义。
  
  写到这里代码部分就完成了,然后运行android项目,就可以看到效果了。
  
  ios
  
  首先也是执行:
  
  flutter create -t module my_flutter
  
  生成一个flutter工程,由于在Android集成中已经做了这一步,故跳过。然后用Xcode创建一个iOS工程,创建完成之后,目录如下:
  
  下面为工程添加flutter的依赖,这里要使用cocoapods,若以前没有安装过,则执行命令:
  
  sudo gem install cocoapods
  
  然后在iOS工程的根目录创建Podfile文件,命令为:
  
  touch Podfile
  
  然后修改podfile文件,如下:
  
  target 'ios4Flutter' do
  
  platform:ios,'8.0'
  
  flutter_application_path www.mhylpt.com= '../my_flutter/'
  
  eval(File.read(File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')), binding)
  
  end
  
  其中ios4Flutter为我的iOS工程名,flutter_application_path为flutter工程的根目录。
  
  最后执行:
  
  pod install
  
  完成项目的依赖,效果如下:
  
  之后点击.xcworkSpace文件打开iOS工程,找到Build Phases目录,新建一个Script Phase,粘贴下面的命令:
  
  "$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh" build
  
  "$FLUTTER_ROOT/packages/flutter_www.gcyL157.com tools/bin/xcode_backend.sh" embed
  
  到text area,如下图:
  
  配置完成之后,⌘B来build工程。如果没有报错,那么部署成功。下面开始写代码:
  
  在AppDelegate.h中:
  
  #import <UIKit/UIKit.h>
  
  #import <Flutter/Flutter.h>
  
  @interface AppDelegate : FlutterAppDelegate
  
  @end
  
  AppDelegate.m:
  
  #import <FlutterPluginRegistrant/GeneratedPluginRegistrant.h> // Only if you have Flutter Plugins
  
  #include "AppDelegate.h"
  
  @implementation AppDelegate
  
  // This override can be omitted if you do not have any Flutter Plugins.
  
  - (BOOL)application:www.gcyl152.com/ (UIApplication *)application
  
  didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  
  [GeneratedPluginRegistrant registerWithRegistry:self];
  
  return [super application:application didFinishLaunchingWithOptions:launchOptions];
  
  }
  
  @end
  
  ViewController.m:
  
  #import <Flutter/Flutter.h>
  
  #import "ViewController.h"
  
  @implementation ViewController
  
  - (void)viewDidLoad www.feifanyule.cn{
  
  [super viewDidLoad];
  
  UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
  
  [button addTarget:self
  
  action:@selector(handleButtonAction)
  
  forControlEvents:UIControlEventTouchUpInside];
  
  [button setTitle:@"Press me" forState:UIControlStateNormal];
  
  [button setBackgroundColor:[UIColor blueColor]];
  
  button.frame = CGRectMake(80.0, 210.0, 160.0, 40.0);
  
  [self.view addSubview:button];
  
  }
  
  - (void)handleButtonAction {
  
  FlutterViewController* flutterViewController = [[FlutterViewController alloc] init];
  
  [flutterViewController setInitialRoute:@"route1"];
  
  [self presentViewController:flutterViewController animated:false completion:nil];
  
  }
  
  @end
  
  OK,oc代码编写完成,运行app,呈现效果。
  
  Hot restart/reload and debugging Dart code
  
  我们可以运用dart语言的特性实现 hot reload,首先在flutter的根目录执行:
  
  flutter attach
  
  如下:
  
  当运行完app,点击按钮进入flutter的view时,终端状态如下:
  
  当我们再次修改dart代码,保存之后,在命令中输入r即可hot reload。

在Android和iOS中集成flutter的更多相关文章

  1. 现有项目中集成Flutter

    本文列举了项目开发使用Flutter会遇到的问题,以及如何使用Flutter module在现有项目中集成Flutter,并对其原理进行了分析. 最近在做的一个商业项目,完全的使用Flutter编写的 ...

  2. Unity在Android和iOS中如何调用Native API

    本文主要是对unity中如何在Android和iOS中调用Native API进行介绍. 首先unity支持在C#中调用C++ dll,这样可以在Android和iOS中提供C++接口在unity中调 ...

  3. 如何在ios中集成微信登录功能

    在ios中集成微信的登录功能有两种方法 1 用微信原生的api来做,这样做的好处就是轻量级,程序负重小,在Build Settings 中这样设置 然后设置 友盟的设置同上,但是要注意,加入你需要的所 ...

  4. Android 和iOS 中关于View 的一点知识

    View的概念和方法十分重要,这里将对Android 和iOS中出现的,关于视图的一些知识点进行总结,预计文章会比较长,要许多时间慢慢补充. 先转载一部分资料,感谢原作者! 原链接为:http://b ...

  5. Android Studio 项目中集成百度地图SDK报Native method not found: com.baidu.platform.comjni.map.commonmemcache.JNICommonMemCache.Create:()I错误

    Android Studio 项目中集成百度地图SDK报以下错误: java.lang.UnsatisfiedLinkError: Native method not found: com.baidu ...

  6. iOS中集成ijkplayer视频直播框架

    ijkplayer 是一款做视频直播的框架, 基于ffmpeg, 支持 Android 和 iOS, 网上也有很多集成说明, 但是个人觉得还是不够详细, 在这里详细的讲一下在 iOS 中如何集成ijk ...

  7. Android 和iOS中 Gesture 和 Touch

    先谈谈在开发中遇到的手势问题: 今天在开发android程序时,在 View.OnTouchListener 的 onTouch(View view, MotionEvent motionEvent) ...

  8. Android和iOS中Cocos2D日志为什么会出现skip frames

    在你运行app在Android或iOS设备或iOS模拟器中时,日志里往往会出现一行: I/Choreographer(28956): Skipped 159 frames! The applicati ...

  9. 直播软件开发关于Android、iOS中的视频采集步骤

    很多人对直播软件开发还是抱有想法的,但是在这个资本冷静的市场下,直播平台该怎么玩,在直播软件开发过程中哪些功能是必须具备的,这都是值得关注的话题.今天我们给大家分享一份详细的直播软件开发关于Andro ...

随机推荐

  1. Java分享笔记:Map集合(接口)的基本方法程序演示

    package pack02; import java.util.*; public class MapDemo { public static void main(String[] args) { ...

  2. js | JavaScript中数据类型转换总结

    转载 在js中,数据类型转换分为显式数据类型转换和隐式数据类型转换. 1, 显式数据类型转换 a:转数字: 1)Number转换: 代码: var a = “123”; a = Number(a); ...

  3. 前端vue项目部署到tomcat,一刷新报错404解决方法

    公司前端写的后台部署到tomcat webapps目录下后,无法进行刷新,一刷新就会报错404,自动跳的404页面.在网上查了下,官方说是HTML5 History 模式引发的问题,但是解决方案中,并 ...

  4. JAVA / MySql 编程——第八章 DAO 模式

    1.        数据持久化:将程序中的数据在瞬时状态和持久状态间转换的机制即为数据持久化: 2.        持久化的实现方式:数据库.普通文件.XML文件: 3.        JDBC封装: ...

  5. ajax状态值和状态码

    AJAX状态值是指,运行AJAX所经历过的几种状态,无论访问是否成功都将响应的步骤,可以理解成为AJAX运行步骤.如:正在发送,正在响应等,由AJAX对象与服务器交互时所得:使用“ajax.ready ...

  6. java中的构造方法(2013-05-05-bd 写的日志迁移

    特点: 1.方法名和类名相同 2.没有返回值 3.在创建一个类的新对象时,系统会自动的调用该类的构造方法完成对新对象的初始化 一个类中可以定义多个不同构造方法: 如果程序员没有定义构造方法,系统能够会 ...

  7. <Docker学习>4. docker容器的使用

    简单的说, 容器是独立运行的一个或一组应用, 以及它们的运行态环境. 对应的, 虚拟机可以理解为模拟运行的一整套操作系统( 提供了运行态环境和其他系统环境) 和跑在上面的应用.容器的运行是基于镜像的. ...

  8. Alice’s Stamps HDU - 6249 (区间DP)

    点击传送 Alice’s Stamps Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Othe ...

  9. Oozie 实战之 Hive

    1.编辑job.propertiers nameNode=hdfs://cen-ubuntu.cenzhongman.com:8020 jobTracker=localhost:8032 queueN ...

  10. 20145202 《Java程序设计》实验四实验报告

    实验名称 Andoid开发基础 实验内容 1.基于Android Studio开发简单的Android应用并部署测试; 2.了解Android组件.布局管理器的使用: 3.掌握Android中事件处理 ...