Android原生项目集成flutter项目混合开发详解

Android原生项目集成flutter项目混合开发

方案挑选:java

目前主要有两种集成方式:android

一、源码集成:就是谷歌官方提供的方案( https://github.com/flutter/flutter/wiki/Add-Flutter-to-existing-apps )git

二、 产物集成: Flutter项目单独开发,开发完成后发布成安卓以aar包,iOS的framework形式,原生项目依赖flutter输出的制品就能够了,具体能够看闲鱼的文章,他们就是这么干的,借用网上的一张图github

两种方案各有优劣,鉴于咱们项目参与人数众多,若是采用源码集成的方式,全部人都得配相应的环境和了解相关的知识,显然成本较高,全部咱们选择了第二种方式,专门几我的去作flutter项目而后以AAR包的方式集成到项目中来web

这篇文章里我两种都尝试一下,固然我是安卓这边的尝试闭包

方式1、源码集成的方式,项目里直接引入flutter module

直接从AS的图形界面导入已经新建的flutter module尝试失败app

这样导入flutter module失败svg

正确打开方式:post

一、使用Android Studio来建立Flutter Module(放在原生的同级目录)gradle

一、 依次点击左上角的File --> New --> New Flutter Project

二、而后选择Flutter Module。

如图:

二、在项目的根目录settings.gradle文件中配置:

include ':app'
include ':flutter_module'
setBinding(new Binding([gradle: this]))
evaluate(new File(        
    settingsDir.parentFile,        
    '主项目名称/flutter_module名称/.android/include_flutter.groovy'))

关于这个配置,new File(settingsDir.parentFile,‘my_flutter/.android/include_flutter.groovy’ ) 解读下这句话的意思就是指定 include_flutter.groovy 的所在位置。这里的意思是在 settings 文件所在目录(settingsDir)的父目录有个文件(settingsDir.parentFile)my_flutter/.android/include_flutter.groovy。看下下面的文件放置位置图就清楚了:

因此官网在跟项目同级建立 flutter module 是没问题的。可是咱们如今改了,应该怎样设置呢?

Tips:注意相对路径的使用,重点是找到 include_flutter.groovy

解法一:

include ':app'
setBinding(new Binding([gradle: this]))         
evaluate(new File(                                        
        settingsDir,                                  
        'sub/my_flutter/.android/include_flutter.groovy'    
))

在 settings 所在目录有 sub/my_flutter/.android/include_flutter.groovy 文件
解法二:

include ':app'
setBinding(new Binding([gradle: this]))        
evaluate(new File(                                          
        settingsDir.parentFile,                                   
        'MyApp/sub/my_flutter/.android/include_flutter.groovy'   
))

在 settings 所在目录的父目录有 MyApp/sub/my_flutter/.android/include_flutter.groovy 文件
这里我用了第二种方案
参考:http://www.javashuo.com/article/p-wvvfhsmw-cq.html
三、在app下的gradle文件中添加

implementation project(':flutter')

完成这三步就顺利完成在原生项目中集成flutter module了

安卓原生界面跳转到flutter界面有两种方式,一种是使用flutterView,另外一种是使用 FlutterFragment ,这里我选择了前者

先新建一个activity,FlutterViewActivty(随意命名),在oncreate方法中加入如下代码

private fun initView() { 
 
  
        val flutterView: View = Flutter.createView(this, lifecycle, "flutter Route1")
        val layoutParams = FrameLayout.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
        addContentView(flutterView, layoutParams)
    }

Flutter.createView()方法返回的是一个FlutterView,它继承自View,咱们能够把它当作一个普通的View,调用addContentView()方法将这个View添加到Activity的contentView中。咱们注意到Flutter.createView()方法的第三个参数传入了"flutter Route1"字符串,表示路由名称,它肯定了Flutter中要显示的Widget,接下来须要在以前建立好的Flutter Module中编写逻辑了,修改main.dart文件中的代码
``

Widget _widgetForRoute(String route) { 
 
  
  switch (route) { 
 
  
    case "flutter Route1":
      return Scaffold(
        appBar: AppBar(
          title: Text("test native"),
        ),
        body: Center(
          child: Text('flutter 页面,route=$route'),
        ),
      );
    default:
      return Center(
        child: Text('Unknown route: $route', textDirection: TextDirection.ltr),
      );
  }
}

在runApp()方法中经过window.defaultRouteName能够获取到咱们在Flutter.createView()方法中传入的路由名称,即"flutter Route1",以后编写了一个_widgetForRoute()方法,根据传入的route字符串显示相应的Widget。

最后在Mainacivity中加入跳转事件

switch (v.getId()) { 
 
  
            case R.id.btn_flutter:
                Intent intent = new Intent(MainActivity.this, FlutterViewActivity.class);
                startActivity(intent);
                break;
        }

大功告成!!

可是发现原生的标题栏还在,在style中加入透明标题栏样式

<style name="FlutterTheme" parent="AppTheme.NoActionBar">
        <item name="android:windowTranslucentStatus">true</item>
    </style>

顺利完成,如图,点击跳转的时候会有黑屏一下的现象,不过没事,这是debug状况才会有的,debug有一些调试的预加载,打了release包以后就没有这个现象了

方案2、AAR方式集成

一、Android 原工程须要使用 java 8 编译

在 工程的 build.gradle 里面,android {} 下修改

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

二、生成 aar 文件

经过集成 arr 的方式须要先生成 Flutter Module 的 arr,在 Flutter Module 的根目录下运行如下命令

flutter build aar

三、使用 aar

主工程的 build.gradle repositories 闭包 里面加入

flatDir { 
 
  
            dirs 'libs'   // aar目录
        }

而后把AAR包复制到libs目录下面, app 的 build.gradle 里面添加依赖

implementation (name:'flutter-release-old',ext:'aar')

跳转的代码和方式一同样不用动,编译运行以后成功

参考:
https://www.jianshu.com/p/5ef007d83b34
https://www.jianshu.com/p/7b6522e3e8f1