Flutter 项目品种
enum FlutterProjectType {
app, // Flutter项目,主体是Flutter。
module, // 主体是原生项目,用于在原生iOS、Android项目中增加Flutter模块,用于原生与Flutter混合开发。
package, // 纯Flutter模块,不需求原生代码完成
plugin, // 原生模块,在Flutter项目引进插件来完成原生的功用。
}
本文主要剖析 app
类型的创立过程,其他类型的原理类似
源码目录
翻开 flutter/packages/flutter_tools/lib/src/commands/create.dart
文件
可以看到类名是 CreateCommand
, runCommand()
函数是类的主函数
runCommand 主要流程
Future<FlutterCommandResult> runCommand() async {
final FlutterProjectType template = _getProjectType(projectDir); // 项目类型, app/module....
final List<String> platforms = stringsArg('platforms'); // 支撑系统渠道: ios/android/web...
final String organization = await getOrganization(); // 项目组织称号
final bool overwrite = boolArgDeprecated('overwrite'); // 是否掩盖已经存在的文件
final String dartSdk = globals.cache.dartSdkBuild; // dart版本
final bool includeIos; // 是否包括iOS项目
final bool includeAndroid; // 是否包括Android项目
final bool includeWeb; // 是否包括Web项目
final bool includeLinux; // 是否包括Linux项目
final bool includeMacos; // 是否包括MacOS项目
final bool includeWindows; // 是否包括Windows项目
if (template == FlutterProjectType.module) { // module 只支撑Android和iOS渠道
includeIos = true;
includeAndroid = true;
includeWeb = false;
includeLinux = false;
includeMacos = false;
includeWindows = false;
} else {
includeIos = featureFlags.isIOSEnabled && platforms.contains('ios');
includeAndroid =
featureFlags.isAndroidEnabled && platforms.contains('android');
includeWeb = featureFlags.isWebEnabled && platforms.contains('web');
includeLinux = featureFlags.isLinuxEnabled && platforms.contains('linux');
includeMacos = featureFlags.isMacOSEnabled && platforms.contains('macos');
includeWindows =
featureFlags.isWindowsEnabled && platforms.contains('windows');
}
String? developmentTeam; // 获取iOS 的开发Team
if (includeIos) {
developmentTeam = await getCodeSigningIdentityDevelopmentTeam(
processManager: globals.processManager,
platform: globals.platform,
logger: globals.logger,
config: globals.config,
terminal: globals.terminal,
);
}
// Flutter要求项目称号小写驼峰命名
final String titleCaseProjectName = snakeCaseToTitleCase(projectName);
// 项目信息Map
final Map<String, Object?> templateContext = createTemplateContext(
organization: organization, // 项目组织
projectName: projectName, // 项目称号
titleCaseProjectName: titleCaseProjectName,
projectDescription: stringArgDeprecated('description'), // 项目描绘
flutterRoot: flutterRoot, // flutter根目录
androidLanguage: stringArgDeprecated('android-language'), // Android 运用的言语 Java/Kotlin
iosLanguage: stringArgDeprecated('ios-language'), // iOS 运用的言语 OC/Swift
iosDevelopmentTeam: developmentTeam, // iOS 开发team 称号
ios: includeIos, // 是否包括iOS项目
android: includeAndroid, // 是否包括Android项目
web: includeWeb, // 是否包括 Web 项目
linux: includeLinux, // 是否包括 Linux 项目
macos: includeMacos, // 是否包括 MacOS项目
windows: includeWindows, // 是否包括 Windows 项目
dartSdkVersionBounds: "'>=$dartSdk <3.0.0'", // dart版本
implementationTests: boolArgDeprecated('implementation-tests'),
agpVersion: gradle.templateAndroidGradlePluginVersion,
kotlinVersion: gradle.templateKotlinGradlePluginVersion, // kotlin版本
gradleVersion: gradle.templateDefaultGradleVersion, // gradle版本
);
final bool creatingNewProject =
!projectDir.existsSync() || projectDir.listSync().isEmpty;
final Directory relativeDir = globals.fs.directory(projectDirPath);
int generatedFileCount = 0;
PubContext pubContext = PubContext.create;
switch (template) {
case FlutterProjectType.app:
generatedFileCount += await generateApp( // generateApp办法去生成 App
<String>['app', 'app_test_widget'],
relativeDir,
templateContext,
overwrite: overwrite,
printStatusWhenWriting: !creatingNewProject,
projectType: template,
);
pubContext = PubContext.create;
break;
case FlutterProjectType.module:
generatedFileCount += await _generateModule(
relativeDir,
templateContext,
overwrite: overwrite,
printStatusWhenWriting: !creatingNewProject,
);
pubContext = PubContext.create;
break;
}
if (boolArgDeprecated('pub')) { // 更新Flutter pub依赖
final FlutterProject project = FlutterProject.fromDirectory(relativeDir);
await pub.get(
context: pubContext,
project: project,
offline: boolArgDeprecated('offline'),
);
}
return FlutterCommandResult.success();
}
templates(模版)目录
flutter/packages/flutter_tools/templates
中存放各个projectType的模版项目和文件
- android + android-java/android-kotlin
- ios + ios-objc/ios-swift
generaeApp()
从 flutter/packages/flutter_tools/templates
中复制项目和文件到目标directory
Future<int> generateApp(
List<String> templateNames,
Directory directory,
Map<String, Object?> templateContext, {
bool overwrite = false,
bool pluginExampleApp = false,
bool printStatusWhenWriting = true,
bool generateMetadata = true,
FlutterProjectType? projectType,
}) async {
int generatedCount = 0;
/// 复制 'app', 'app_test_widget', 'app_shared'三个目录文件
generatedCount += await renderMerged(
<String>[...templateNames, 'app_shared'],
directory,
templateContext,
overwrite: overwrite,
printStatusWhenWriting: printStatusWhenWriting,
);
if (templateContext['android'] == true) { // 假如包括Android工程,则缓存Gradle
generatedCount += _injectGradleWrapper(project);
}
if (androidPlatform) { // android 渠道需求额定更新属性
gradle.updateLocalProperties(project: project, requireAndroidSdk: false);
}
// 返回生成了多少个文件
return generatedCount;
}
创立成功