在软件开发界,项目整合策略是团队协作和项目进展的核心。特别是那些包含众多步骤和关键点的整合方案,更需要我们进行深入研究。这正是我们今天要详细讲解的重点所在。
项目开发与封装形式
独立开展开发项目有多项优势。比如,在规模较大的项目中,不同模块的开发周期和功能特点往往相差甚远,可以各自独立进行开发。完成开发后,成果可以打包成aar包或iOS版本。以2022年某公司的项目为例,他们针对安卓和iOS平台就采取了这种策略,便于不同原生项目引用。这种做法能有效提升开发速度,同时减少项目整体出错的可能性。各组件独立开发后,便于封装和测试。原生项目则可以直接依据不同平台的需求,利用这些成品进行后续工作。
flutter channel master
flutter create -t module {moduleName}
这种方法并非完全容易。必须严格遵循开发标准,而不同的呈现方式可能遇到的技术难题也不尽相同。以aar包为例,就需要关注其兼容性问题。
➜ flutter create -t module flutter_module
Creating project flutter_module...
flutter_module/test/widget_test.dart (created)
...
...
flutter_module/.idea/workspace.xml (created)
Running "flutter packages get" in flutter_module... 7.2s
Wrote 12 files.
All done!
Your module code is in flutter_module/lib/main.dart.
谷歌参考下的独特创造
➜ flutter_module git:(master) ✗ tree -L 2 -a
.
├── .android
│ ├── Flutter
│ ├── app
│ ├── ...
├── .gitignore
├── .ios
│ ├── Config
│ ├── Flutter
│ ├── ...
│ └── Runner.xcworkspace
├── lib
│ └── main.dart
├── pubspec.lock
├── pubspec.yaml
└── test
└── widget_test.dart
整体上,我们的集成方案借鉴了谷歌的方法,但也有一些独特创新。项目完成后,我们用git来管理,这样的管理方式让项目更有条理。拿一家互联网初创公司来说,因为外包和内部开发团队人员众多,若没有git这样的优秀版本管理工具,很容易出现版本混乱等问题。
我们并未完全依照谷歌的做法,而是自项目一开始便采用了git进行管理。这种方式非常适合团队共同进行软件开发。它能够较为精确地记录项目中的变动情况,使得团队成员即便在不同时间也能清晰了解自己的任务。然而,这也意味着开发者需要具备一定的git操作技能,只有熟练运用git命令,项目才能更高效地向前推进。
➜ cd flutter_module
➜ git init
Initialized empty Git repository in /Users/zhiqiangdeng/Documents/ProjectSource/FlutterProject/flutter_module/.git/
➜ flutter_module git:(master) ✗
模块项目目录结构
模块项目里有个特别的文件组织形式,里面有隐藏的点和ios目录。这两个目录里藏着不少学问。2021年,在一个中等规模的软件开发项目中,开发者一开始对这种结构挺困惑,但后来明白了,原来可执行的项目结构和iOS项目都藏在这些目录里。尽管代码主要在lib目录下编写,但点和ios目录各自管理着各自的库项目。这种结构在开发过程中清晰界定了各个部分的功能和类型。
-.android/
-.ios/
+.ios/Flutter/Generated.xcconfig
目录结构若特殊,项目难度便随之上升。新成员若要掌握其运作,恐怕需投入不少时间。因此,团队需建立完善的文档和培训体系,否则在复杂结构中容易迷失。
Git管理模块项目
git remote add origin {你的flutter module的仓库地址}
git push origin master
用git对模块项目进行管理是极为关键的。在创建git仓库并编辑项目下的特定文件时,这一环节绝不可省略。以一个软件外包项目为例,若开发团队未正确编辑该文件,可能会导致本应被忽略的文件被错误地忽略,而需要被跟踪的文件却未被纳入跟踪范围。在我们项目中,对于.ios和.这两个目录,我们必须确保正确跟踪,并从网上寻找合适的iOS和模版文件,以补充完善这两个目录的内容。
修改顶层目录文件时,必须谨慎地将’.和.ios’添加为’.ios//.’。这个过程要求极高的精确度。若出现拼写或路径上的任何错误,后续的项目拉取都可能遇到问题,例如,可能无法成功获取完整项目,或者获取到错误的文件版本。
platform :ios, '8.0'
use_frameworks!
target 'MyApp' do
pod 'AFNetworking', '~> 2.6'
xxxx
end
#添加如下两行代码,路径修改为我们的fluter module的路径
flutter_application_path = './flutter-module-demo'
eval(File.read(File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')), binding)
Pod命令相关的配置
"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh" build
"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh" embed
iOS项目操作涉及pod配置。需进入项目根目录,安装git并克隆项目,接着在文件里插入特定代码。.rb文件在此过程中扮演重要角色。2020年,某小型iOS应用开发因.rb文件配置失误,导致项目无法正常运作。它需导入相关配置信息。此外,同级目录下的另一个文件同样至关重要,它影响众多命令执行时的文件生成过程。
在执行pod操作时,文件信息会被记录进xcodebuild。pod执行完毕后,检查信息同样重要。若查询信息不成功,未能正确获取,项目构建过程可能会遇到错误或缺少必要的参数。
项目运行与相关设置
➜ cd flutter-module-demo
➜ flutter-module-demo git:(master) flutter packages get
Running "flutter packages get" in flutter-module-demo... 0.4s
➜ flutter-module-demo git:(master) cd ..
➜ FlutterNativeiOS git:(master) ✗ pod install
Analyzing dependencies
Fetching podspec for `Flutter` from `./flutter-module-demo/.ios/Flutter/engine`
Fetching podspec for `FlutterPluginRegistrant` from `./flutter-module-demo/.ios/Flutter/FlutterPluginRegistrant`
Downloading dependencies
Using AFNetworking (2.6.3)
Installing Flutter (1.0.0)
Installing FlutterPluginRegistrant (0.0.1)
Generating Pods project
Integrating client project
Sending stats
Pod installation complete! There are 3 dependencies from the Podfile and 3 total pods installed.
项目运行阶段至关重要。在执行构建阶段时,加入.sh脚本并运用先前pod为xcode构建配置的环境变量,这种做法相当巧妙。此外,原生项目中加入子模块,在安卓项目中的运用同样不容忽视。比如,在某个混合项目开发中,将上述创建的项目引入原生安卓项目,大大增强了其功能。
import UIKit
import Flutter
import FlutterPluginRegistrant // Only if you have Flutter Plugins.
@UIApplicationMain
class AppDelegate: FlutterAppDelegate {
var flutterEngine : FlutterEngine?;
// Only if you have Flutter plugins.
override func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
self.flutterEngine = FlutterEngine(name: "io.flutter", project: nil);
self.flutterEngine?.run(withEntrypoint: nil);
GeneratedPluginRegistrant.register(with: self.flutterEngine);
return super.application(application, didFinishLaunchingWithOptions: launchOptions);
}
}
在原生项目的app文件夹中的build文件里加入库的依赖同样关键,这关乎到版本信息的搜集和统一。若团队成员未按此规范操作,比如未使用${HOME}目录下对应版本的sdk包,可能会造成程序无法启动或运行时出错。
关于这个综合且繁复的项目开发及整合过程,您有何独到看法或疑问想交流?期待大家点赞并转发此文,让更多人从中获益。
import UIKit
import Flutter
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let button = UIButton(type:UIButtonType.custom)
...
self.view.addSubview(button)
}
@objc func handleButtonAction() {
let flutterEngine = (UIApplication.shared.delegate as? AppDelegate)?.flutterEngine;
let flutterViewController = FlutterViewController(engine: flutterEngine, nibName: nil, bundle: nil)!;
self.present(flutterViewController, animated: true, completion: nil)
}