Flutter 添加到现有项目
source link: http://mp.weixin.qq.com/s?__biz=MzIxNzU1Nzk3OQ%3D%3D&%3Bmid=2247489954&%3Bidx=1&%3Bsn=a03d1b8c93015e73dbee1c36ef01bf9b
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
code小生
一个专注大前端领域的技术平台
公众号回复 Android
加入安卓技术群
作者:言就尔宿1992
链接:https://www.jianshu.com/p/9425dd2baacc
声明:本文已获 言就尔宿1992
授权发表,转发等请联系原作者授权
Flutter 添加到现有项目 (Android)
最近一直在看Flutter 的内容, 加上近期更新的Flutter1.12 有一些Flutter 的api 发生了改变, 所以 某些和android 交互的地方 就发生了变化
比如开始使用的新的插件api 旧的 PluginRegistry.Registrar 不会立即被弃用, 而使用了新的FlutterPlugin, FlutterActivity 的 从io.flutter.app.FlutterActivity 到 io.flutter.app.FlutterActivity
接下来 就是 添加到现有项目步骤 基于androdx
-
创建一个原生的Android项目 直接通过AndroidStudio 创建一个androd 项目
-
然后在AS 中 通过 new Project 选择 FlutterModule 创建一个Flutter module 创建的时候记得 勾选androidx
-
再 androd项目中 app 下 build.gradle 中添加
android{ compileOptions { sourceCompatibility 1.8 targetCompatibility 1.8 } }
然后 再setting.gradle 中添加
setBinding(new Binding([gradle:this])) evaluate(new File( settingsDir.parentFile, '你的flutter module 的名字/.android/include_flutter.groovy' ))
编译
然后成功之后再android 项目中的 build.gradle 中添加
implementation project(path: ':flutter')
编译
调整Flutter 库中关联的.android 中的flutter 的库 中的build.gradle 的 compileSdkVersion minsdkVersion 以及 targetSdkVersion和主项目保持一致,
我用的是 在acticity 中 添加FlutterFragement 首先 Activity 继承 FragmentActivity
对了如果 Android 项目中是androdx 的话 需要再 Flutter项目中修改 pubspec.yaml
moudule 下的 androidX 是否为true;
接下来是我 Flutter 项目中的代码 就是 官方生成的代码 自己稍微改了下
import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: MyHomePage(title: 'Flutter Demo Home Page'), ); } } class MyHomePage extends StatefulWidget { MyHomePage({Key key, this.title}) : super(key: key); final String title; @override _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { static const platform = const MethodChannel("com.battery.io/battery"); String _battery = "获取电池电量"; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.title), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Text( _battery ), ], ), ), floatingActionButton: FloatingActionButton( onPressed: _getBatteryLevel, tooltip: 'Increment', child: Icon(Icons.add), ), // This trailing comma makes auto-formatting nicer for build methods. ); } Future<Null> _getBatteryLevel() async { String battery = "获取电池电量"; try { int result = await platform.invokeMethod("getBatteryLevel"); battery = "获取到的电量 $result"; } on PlatformException catch (e) { // 未获取到电池电量 battery = "未获取到电池电量"; } setState(() { _battery = battery; }); } }
其实 这篇文章主要就是记录了 fragment 和flutter 的交互
此处写了一个方法 通过Flutter 中的方法来调用 android 中的方法 我是通过 android 中添加一个Fragment 来加载Flutter 的界面
先上代码 --> Activity
package com.storm.stormandflutterdemo import android.app.Activity import android.content.Intent import android.os.Bundle import androidx.fragment.app.FragmentActivity import com.storm.stormandflutterdemo.Utils.LogUtils import com.storm.stormandflutterdemo.flutterplugin.BatteryPlugin import io.flutter.embedding.android.FlutterFragment import io.flutter.embedding.engine.FlutterEngine import io.flutter.embedding.engine.FlutterEngineCache import io.flutter.embedding.engine.dart.DartExecutor class CustomActivity : FragmentActivity() { companion object { val TAG_FLUTTER_FRAGMENT = "flutter_fragment" val TAG = "CustomActivity" fun startSelf(activity: Activity) { var intent = Intent(activity, CustomActivity::class.java) activity.startActivity(intent) } } var flutterFragment: FlutterFragment? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_custom) startFlutter() } private fun startFlutter() { initPlugin() var fm = supportFragmentManager flutterFragment = fm.findFragmentByTag(MainActivity.TAG_FLUTTER_FRAGMENT) as FlutterFragment? if (flutterFragment == null) { var newFlutterFragment = FlutterFragment.withCachedEngine("my_flutter").build<FlutterFragment>() flutterFragment = newFlutterFragment fm.beginTransaction() .add(R.id.fl_content, flutterFragment!!, MainActivity.TAG_FLUTTER_FRAGMENT).commit() LogUtils.d(TAG, "是否未null ? --> ${null == flutterFragment}") flutterFragment!!.onAttach(this) } } private fun initPlugin() { var flutterEngine = FlutterEngine(this) flutterEngine.dartExecutor.executeDartEntrypoint(DartExecutor.DartEntrypoint.createDefault()) FlutterEngineCache.getInstance() .put("my_flutter",flutterEngine) BatteryPlugin.registerWith(flutterEngine) } override fun onResume() { super.onResume() } }
此处 有个问题 就是我当时再创建FlutterFragment 总是爆红 开始的时候 发现导入的包不一样
FlutterFragment 用的是 v4包,而我用的是androidx 的包, 其实我可以改成v4包的 但是考虑到以后 api 29 以后 的 会维护androidX 而放弃androd v4 v7 各个版本的维护 所以自己就钻牛角尖, 索性都换成androdX 的去寻找方法
查过来查过去 FlutterFragment 的继承的Fragment 始终是v4 包下的Fragment 即使我删除了这个FlutterModule 重新创建的开始勾选了androidX 还是 v4包 , 在Android项目中 中 还是爆红...
妈蛋 结果就是 我试着运行 竟然正常运行 ... enen . 这边还爆红 也Flutter 加载出来了 .........###Fuck说
另一方面就是 Flutter1.12 以后更换了api 因为我也是最近开始看 , 有的地方不是很懂 各位大神觉得有什么不对的地方 留言一起讨论共同进步, 之前的如果要加载插件 , 就是在当前的activity 或者是fragement 中 注册 传入 PluginRegistry.Registrar 记得之前的 FlutterActivity 或者FlutterFragment 都实现了 这个接口, 所以直接传入this 拿到activity 的引用 , 不过在1.12 之后 改成了新的 直接 传入 FlutterEngine 来注册交互的插件。
其实initPlugin 这个方法 放入 Application 中也可以 通过一个tag , 然后 创建 FlutterFragment 的时候通过tag 来创建 , 然后插件注册
插件-->
package com.storm.stormandflutterdemo.flutterplugin import androidx.annotation.Keep import androidx.annotation.NonNull import io.flutter.embedding.engine.FlutterEngine import io.flutter.embedding.engine.plugins.shim.ShimPluginRegistry import io.flutter.plugin.common.MethodChannel import java.lang.reflect.Method /** * * @author storm_z * @date @{DATE} * @email [email protected] * * @Describe */ @Keep object BatteryPlugin { public const val CHANNEL = "com.battery.io/battery" fun registerWith(@NonNull flutterEngine: FlutterEngine){ val shimPluginRegistry = ShimPluginRegistry(flutterEngine) val registrar = shimPluginRegistry.registrarFor("com.battery.io") val context = registrar.activeContext() val channel = MethodChannel(registrar.messenger(), CHANNEL) var value = 0 ; channel.setMethodCallHandler { call, result -> when(call.method){ "getBatteryLevel" -> { value += 20 result.success(value) } } } } }
这次 主要是想要吧 Flutter 放入到 android 的 Fragment 中来尝试 , 看了很多博客 和官方文档 都是介绍怎么在 Fragment 中使用但是交互方面 都是1.12 版本之前的 , 或者说在 FlutterActivity 中的 , 所以 自己在捣鼓出来之后就记录一下 然后有什么问题 一起讨论 共同进步 很少写这个 以后慢慢规范 . 去尝试 FlutterView 了 ......
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK