搭建一个空的Android工程FlutterDemo_Android模拟已经存在的原有工程
Android项目配置:

搭建一个空的iOS工程FlutterDemo_iOS模拟已经存在的原有工程
Xcode项目配置

搭建Pod:
在工程目录下执行
pod init
pod install
这里使用AndroidStudio做Flutter开发环境



flutter_demo_module


dependencies:
flutter:
sdk: flutter
cupertino_icons: ^1.0.2
# add
flutter_boost:
git:
url: 'https://github.com/alibaba/flutter_boost.git'
ref: '4.1.0'
然后执行flutter pub get下载flutter_boost到module中
import 'package:flutter/material.dart';
class WillPopRoute extends StatefulWidget {
const WillPopRoute({Key? key, this.title}) : super(key: key);
final String? title;
@override
State<StatefulWidget> createState() => _WillPopRouteState();
}
class _WillPopRouteState extends State<WillPopRoute> {
bool shouldPop = true;
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: () async {
return shouldPop;
},
child: Scaffold(
appBar: AppBar(
title: const Text('Flutter Demo'),
),
),
);
}
}
import 'package:flutter/material.dart';
import 'package:flutter_boost/flutter_boost.dart';
import 'package:flutter_demo_module/willpop.dart';
void main() {
CustomFlutterBinding();
runApp(const MyApp());
}
class CustomFlutterBinding extends WidgetsFlutterBinding
with BoostFlutterBinding {}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
// 配置路由
static Map<String, FlutterBoostRouteFactory> routerMap = {
'flutterPage': (settings, uniqueId) {
return PageRouteBuilder<dynamic>(
settings: settings, pageBuilder: (_, __, ___) => const WillPopRoute());
}
};
Route<dynamic>? routeFactory(RouteSettings settings, String? uniqueId) {
FlutterBoostRouteFactory? func = routerMap[settings.name!];
if (func == null) {
return null;
}
return func(settings, uniqueId);
}
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return FlutterBoostApp(routeFactory);
}
}
setBinding(new Binding([gradle: this]))
evaluate(new File(
settingsDir.parentFile,
'flutter_demo_module/.android/include_flutter.groovy'
))
include ':flutter_demo_module'
project(':flutter_demo_module').projectDir = new File('../flutter_demo_module')
注意:new Binding([gradle: this])会有红色提示,不用管
<activity
android:name="com.idlefish.flutterboost.containers.FlutterBoostActivity"
android:theme="@style/Theme.AppCompat"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize" >
</activity>
<meta-data android:name="flutterEmbedding"
android:value="2">
</meta-data>
注意这一步之后执行gradle sync,如果遇到问题,可以参考文章最后的问题集锦
自定义Application
class MyApp : Application() {
override fun onCreate() {
super.onCreate()
FlutterBoost.instance().setup(this, object : FlutterBoostDelegate {
override fun pushNativeRoute(options: FlutterBoostRouteOptions) {
// 原生跳转
}
override fun pushFlutterRoute(options: FlutterBoostRouteOptions) {
// Flutter跳转
}
}, FlutterBoost.Callback { engine: FlutterEngine? -> })
}
}
配置app的AndroidManifest
<application
android:name=".MyApp"
...
</application>
val params: Map<String, Any> = HashMap()
val intent: Intent = FlutterBoostActivity.CachedEngineIntentBuilder(
FlutterBoostActivity::class.java
)
.backgroundMode(FlutterActivityLaunchConfigs.BackgroundMode.opaque)
.destroyEngineWithActivity(false)
.url("flutterPage")
.urlParams(params)
.build(context)
startActivity(intent)
flutter_application_path = '../flutter_demo_module'
load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')
install_all_flutter_pods(flutter_application_path)
post_install do |installer|
flutter_post_install(installer) if defined?(flutter_post_install)
end
# Flutter Module Path
# step1 load file
flutter_application_path = '../flutter_demo_module'
load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')
target 'FlutterDemo_iOS' do
# Comment the next line if you don't want to use dynamic frameworks
use_frameworks!
# step2 install function
install_all_flutter_pods(flutter_application_path)
end
# step3 post_install
post_install do |installer|
flutter_post_install(installer) if defined?(flutter_post_install)
end
执行pod install,podhelper.rb 脚本会把你的 plugins, Flutter.framework,和 App.framework 集成到你的项目中。
备注:
Flutter.framework 是 Flutter engine 的框架, App.framework 是你的 Dart 代码的编译产物。
import UIKit
import Flutter
import flutter_boost
import FlutterPluginRegistrant
class MyBoostAppDelegate: NSObject,FlutterBoostDelegate {
static let shared = MyBoostAppDelegate()
///您用来push的导航栏
var navigationController:UINavigationController?
///用来存返回flutter侧返回结果的表
var resultTable:Dictionary<String,([AnyHashable:Any]?)->Void> = [:];
func pushNativeRoute(_ pageName: String!, arguments: [AnyHashable : Any]!) {
//可以用参数来控制是push还是pop
let isPresent = arguments["isPresent"] as? Bool ?? false
let isAnimated = arguments["isAnimated"] as? Bool ?? true
//这里根据pageName来判断生成哪个vc,这里给个默认的了
let targetViewController = UIViewController()
if(isPresent){
self.navigationController?.present(targetViewController, animated: isAnimated, completion: nil)
}else{
self.navigationController?.pushViewController(targetViewController, animated: isAnimated)
}
}
func pushFlutterRoute(_ options: FlutterBoostRouteOptions!) {
let vc:FBFlutterViewContainer = FBFlutterViewContainer()
vc.setName(options.pageName, uniqueId: options.uniqueId, params: options.arguments,opaque: options.opaque)
//用参数来控制是push还是pop
let isPresent = (options.arguments?["isPresent"] as? Bool) ?? false
let isAnimated = (options.arguments?["isAnimated"] as? Bool) ?? true
//对这个页面设置结果
resultTable[options.pageName] = options.onPageFinished;
//如果是present模式 ,或者要不透明模式,那么就需要以present模式打开页面
if(isPresent || !options.opaque){
self.navigationController?.present(vc, animated: isAnimated, completion: nil)
}else{
self.navigationController?.pushViewController(vc, animated: isAnimated)
}
}
func popRoute(_ options: FlutterBoostRouteOptions!) {
//如果当前被present的vc是container,那么就执行dismiss逻辑
if let vc = self.navigationController?.presentedViewController as? FBFlutterViewContainer,vc.uniqueIDString() == options.uniqueId{
//这里分为两种情况,由于UIModalPresentationOverFullScreen下,生命周期显示会有问题
//所以需要手动调用的场景,从而使下面底部的vc调用viewAppear相关逻辑
if vc.modalPresentationStyle == .overFullScreen {
//这里手动beginAppearanceTransition触发页面生命周期
self.navigationController?.topViewController?.beginAppearanceTransition(true, animated: false)
vc.dismiss(animated: true) {
self.navigationController?.topViewController?.endAppearanceTransition()
}
}else{
//正常场景,直接dismiss
vc.dismiss(animated: true, completion: nil)
}
}else{
self.navigationController?.popViewController(animated: true)
}
//否则直接执行pop逻辑
//这里在pop的时候将参数带出,并且从结果表中移除
if let onPageFinshed = resultTable[options.pageName] {
onPageFinshed(options.arguments)
resultTable.removeValue(forKey: options.pageName)
}
}
}
import UIKit
import flutter_boost
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
//创建代理,做初始化操作
let delegate = MyBoostAppDelegate.shared
FlutterBoost.instance().setup(application, delegate: delegate) { engine in
}
return true
}
}
@IBAction func clickButton(_ sender: Any) {
MyBoostAppDelegate.shared.navigationController = self.navigationController
let options = FlutterBoostRouteOptions()
options.pageName = "flutterPage"
FlutterBoost.instance().open(options)
}
setting.gradle修改Model值为RepositoriesMode.PREFER_PROJECT
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.PREFER_PROJECT)
repositories {
google()
mavenCentral()
}
}
这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下
我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的
目录1.AdmobSDK下载地址2.将下载好的unityPackagesdk导入到unity里编辑 3.解析依赖到项目中
1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里
最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路
print"Enteryourpassword:"pass=STDIN.noecho(&:gets)puts"Yourpasswordis#{pass}!"输出:Enteryourpassword:input.rb:2:in`':undefinedmethod`noecho'for#>(NoMethodError) 最佳答案 一开始require'io/console'后来的Ruby1.9.3 关于ruby-为什么不能使用类IO的实例方法noecho?,我们在StackOverflow上
我正在创建一个新的Rails3.1应用程序。我希望这个新应用程序重用现有数据库(由以前的Rails2应用程序创建)。我创建了新的应用程序定义模型,它重用了数据库中的一些现有数据。在开发和测试阶段,一切正常,因为它在干净的表数据库上运行,但是当尝试部署到生产环境时,我收到如下消息:PGError:ERROR:column"email"ofrelation"users"alreadyexists***[err::localhost]:ALTERTABLE"users"ADDCOLUMN"email"charactervarying(255)DEFAULT''NOTNULL但是我在迁移中有这
在我的Rails项目中,我有三个模型:classRecipe:recipe_categorizationsaccepts_nested_attributes_for:recipe_categories,allow_destroy::trueendclassCategory:recipe_categorizationsendclassRecipeCategorization通过这个简单的has_many:through设置,我怎样才能像这样获取给定的食谱:@recipe=Recipe.first并根据现有类别向此食谱添加类别,并在相应类别上对其进行更新。所以:@category=#Exi
我有一个简单的问题,与关联有关。我有一个书的模型,它有_onereservation。预订属于_书本。我想在预订Controller的创建方法中确保在预订时没有预订一本书。换句话说,我需要检查该书是否存在任何其他预订。我该怎么做?编辑:Aaa我做到了,感谢大家的提示,学到了一些新东西。当我尝试提供的解决方案时,出现no_method错误或nil_class等。这让我开始思考,我尝试处理的对象根本不存在。Krule给了我使用book.find的想法,所以我尝试使用它。最终我得到了它的工作:book=Book.find_by_id(reservation_params[:book_id])
这是我在ChefRecipe中的一blockRuby:#ifdatadirdoesn'texist,moveoverthedefaultoneif!File.exist?("/vol/postgres/data")execute"mv/var/lib/postgresql/9.1/main/vol/postgres/data"end结果是:Executingmv/var/lib/postgresql/9.1/main/vol/postgres/datamv:inter-devicemovefailed:`/var/lib/postgresql/9.1/main'to`/vol/post