最近一直在探索android flutter的混合开发,一路遇到了很多的坑,接下来便将这些记录下来,希望能帮助到大家的开发。
flutter常用指令
flutter help create
-h, --help Print this usage information. --[no-]pub Whether to run "flutter pub get" after the project has been created. (defaults to on) --[no-]offline When "flutter pub get" is run by the create command, this indicates whether to run it in offline mode or not. In offline mode, it will need to have all dependencies already available in the pub cache to succeed. --[no-]with-driver-test Also add a flutter_driver dependency and generate a sample 'flutter drive' test. -t, --template=<type> Specify the type of project to create. [app] (default) Generate a Flutter application. [package] Generate a shareable Flutter project containing modular Dart code. [plugin] Generate a shareable Flutter project containing an API in Dart code with a platform-specific implementation for Android, for iOS code, or for both. -s, --sample=<id> Specifies the Flutter code sample to use as the main.dart for an application. Implies --template=app. The value should be the sample ID of the desired sample from the API documentation website (http://docs.flutter.dev). An example can be found at https://master-api.flutter.dev/flutter/widgets/SingleChildScrollView-class.html --list-samples=<path> Specifies a JSON output file for a listing of Flutter code samples that can created with --sample. --[no-]overwrite When performing operations, overwrite existing files. --description The description to use for your new Flutter project. This string ends up in the pubspec.yaml file. (defaults to "A new Flutter project.") --org The organization responsible for your new Flutter project, in reverse domain name notation. This string is used in Java package names and as prefix in the iOS bundle identifier. (defaults to "com.example") --project-name The project name for this new Flutter project. This must be a valid dart package name. -i, --ios-language [objc, swift (default)] -a, --android-language [java, kotlin (default)] --[no-]androidx Generate a project using the AndroidX support libraries
flutter channel
查看当前flutter分支
Flutter channels:
beta
dev
master
* stable
复制代码
flutter doctor
诊断当前flutter配置是否有问题
flutter doctor
诊断当前flutter配置是否有问题
flutter version –force 1.0.0
切换到指定flutter版本
flutter clean
clean当前工程
flutter run
运行当前工程
flutter analyze
分析当前项目dart代码
flutter assemble
构建资源
flutter attach
attach当前项目,通常用于调试
flutter bash-completion
Output command line shell completion setup scripts.
flutter build
编译flutter项目
flutter config
配置flutter设置
flutter devices
查看设备列表
flutter drive
为当前项目运行驱动测试
flutter emulators
查看模拟器列表以及运行
flutter format
格式化dart代码
flutter install
安装flutter项目
flutter logs
查看运行日志
flutter screenshot
对设备进行截图
flutter test
运行flutter单元测试
flutter upgrade
更新flutter 版本
flutter version
查看flutter 版本
flutter常见问题的解决
flutter工程无法进行依赖
可以查看一下.android/Flutter/build.gradle的buildTypes中是否包含app的build.gradle中所需的buildTypes
缺少libflutter.so
flutter项目默认支持的是armeabi-v7a,所以需要在app的gradle中加入如下配置:
ndk {
abiFilters "armeabi-v7a"
}
复制代码
如果还是提示这个错误,则需要在gradle.properties中华加入如下配置:
target-platform=android-arm
复制代码
编译apk成功,但是运行flutter失败,例如:VM snapshot must be valid. /Check failed: vm. Must be able to initialize the VM.
可以尝试flutter clean, 然后flutter run一下项目,再去运行主工程
flutter混淆配置
-keep class io.flutter.app.** {*;}
-keep class io.flutter.plugin.** {*;}
-keep class io.flutter.util.** {*;}
-keep class io.flutter.view.** {*;}
-keep class io.flutter.** {*;}
-keep class io.flutter.plugins.** {*;}
-dontwarn io.flutter.**
跳转flutter所在activity黑屏
val flutterView = Flutter.createView(this, lifecycle, Gson().toJson(map)) val layout = findViewById<FrameLayout>(R.id.flutter_container) layout.visibility = View.INVISIBLE layout.addView(flutterView) val listeners = arrayOfNulls<FlutterView.FirstFrameListener>(1) listeners[0] = FlutterView.FirstFrameListener { layout.visibility = View.VISIBLE loadingDialog.dismiss() } flutterView.addFirstFrameListener(listeners[0])
或者设置当前主题
flutter的activity进入加载较慢
debug包这种情况比较明显,但是release加载很快,可以仿照一下闲鱼,在进入FlutterActivity的时候提供一个加载loading
Activity中加载flutter几种方式
直接加载flutter的main.dart
GeneratedPluginRegistrant.registerWith即可
public class MainActivity extends FlutterActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GeneratedPluginRegistrant.registerWith(this);
}
}
继承FlutterActivity
class TestFlutterActivity : FlutterActivity() {
private lateinit var flutterFragment: FlutterFragment
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// setContentView(R.layout.activity_flutter_test)
GeneratedPluginRegistrant.registerWith(this)
}
override fun createFlutterView(context: Context?): FlutterView {
val matchParent = WindowManager.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
val nativeView = this.createFlutterNativeView()
val flutterView = FlutterView(this, null, nativeView)
flutterView.setInitialRoute("web_view_page")
flutterView.layoutParams = matchParent
// flutterView.enableTransparentBackground()
val layout = findViewById<FrameLayout>(R.id.flutter_container)
val listeners = arrayOfNulls<FlutterView.FirstFrameListener>(1)
listeners[0] = FlutterView.FirstFrameListener {
layout.visibility = View.VISIBLE
}
flutterView.addFirstFrameListener(listeners[0])
this.addContentView(flutterView, matchParent)
return flutterView
}
override fun onBackPressed() {
if (flutterView != null) {
flutterView.popRoute()
} else {
super.onBackPressed()
}
}
}
复制代码
addContentView直接加载FlutterView
通过FlutterFragment
Android原生与Flutter间的通信、传值
可以通过flutter_boost,但是目前有适配问题,不支持flutter1.7、1.9
Flutter传值->Android
有点类似于Eventbus的方式:
flutter.dart中发送事件:
android接收并处理:
Android传值->Flutter
android跳转flutter的时候可以通过路由名字直接传入值。
dart:
在_getWidgetPage内配置路由跳转的值及对应界面。
android
与之前主要的区别在于参数通过hashmap转换成json形式放入路由名称中,然后把路由名连同参数一起传给main.dart
android部分的封装
我这里对其android部分进行了封装,需要使用的话直接拷贝代码即可:
BaseFlutterActivity:
使用:
class FlutterWebActivity : BaseAegisFlutterActivity() {
private val title: String by lazy { intent.getStringExtra(TITLE) }
private val url: String by lazy { intent.getStringExtra(URL) }
companion object {
const val TITLE = "title"
const val URL = "url"
fun buildIntent(context: Context?, title: String, url: String): Intent {
val intent = Intent(context, FlutterWebActivity::class.java)
intent.putExtra(TITLE, title)
intent.putExtra(URL, url)
return intent
}
}
override fun routeUrl(): String = "web_view_page"
override fun routeParams(): HashMap<String, String> {
val params = HashMap<String, String>()
params["title"] = title
params["url"] = url
return params
}
override fun setChannel(): String = "webview"
override fun setFlutterMessageHandler(): MethodChannel.MethodCallHandler? {
return MethodChannel.MethodCallHandler { methodCall, _ ->
if (methodCall.method == "finish") {
finish()
}
}
}
}
总结
Android Flutter的混合开发基础先总结到这里,希望能帮助到大家。后续内容我会再进行补充。
喜欢 就关注吧,欢迎投稿!
本网站文章均为原创内容,并可随意转载,但请标明本文链接
如有任何疑问可在文章底部留言。为了防止恶意评论,本博客现已开启留言审核功能。但是博主会在后台第一时间看到您的留言,并会在第一时间对您的留言进行回复!欢迎交流!
本文链接: https://leetcode.jp/androidflutter混合开发问题总结/