Improve Android builds. (#9801)
Eagerly generate local.properties, and always update the flutter.sdk
setting in it, in case FLUTTER_ROOT has changed.
Fixes #8365.
Fixes #9716 - at least the specific issue reported. My Android Studio
still complains about Gradle versions - it ships with v3.2, but requires
v3.3...
Add a 'generate dependencies' task to the Gradle build, which checks if
the snapshot dependencies file exists, and runs an extra build before
the actual FlutterTask if it doesn't. This makes the first build slower,
but sub-sequent builds (without source changes) much faster.
Fixes #9717.
diff --git a/packages/flutter_tools/lib/src/android/gradle.dart b/packages/flutter_tools/lib/src/android/gradle.dart
index 3b17ed1..294b9e2 100644
--- a/packages/flutter_tools/lib/src/android/gradle.dart
+++ b/packages/flutter_tools/lib/src/android/gradle.dart
@@ -78,7 +78,7 @@
// Note: this call takes about a second to complete.
String _calculateGradleAppOutDirV2() {
final String gradle = ensureGradle();
- ensureLocalProperties();
+ updateLocalProperties();
try {
final String properties = runCheckedSync(
<String>[gradle, 'app:properties'],
@@ -141,28 +141,42 @@
return gradle;
}
-/// Create android/local.properties if needed.
-File ensureLocalProperties() {
- final File localProperties = fs.file('android/local.properties');
- if (!localProperties.existsSync()) {
- localProperties.writeAsStringSync(
- 'sdk.dir=${escapePath(androidSdk.directory)}\n'
- 'flutter.sdk=${escapePath(Cache.flutterRoot)}\n'
- );
+/// Create android/local.properties if needed, and update Flutter settings.
+void updateLocalProperties({String projectPath, String buildMode}) {
+ final File localProperties = (projectPath == null)
+ ? fs.file(fs.path.join('android', 'local.properties'))
+ : fs.file(fs.path.join(projectPath, 'android', 'local.properties'));
+ bool changed = false;
+
+ SettingsFile settings;
+ if (localProperties.existsSync()) {
+ settings = new SettingsFile.parseFromFile(localProperties);
+ } else {
+ settings = new SettingsFile();
+ settings.values['sdk.dir'] = escapePath(androidSdk.directory);
+ changed = true;
}
- return localProperties;
+ final String escapedRoot = escapePath(Cache.flutterRoot);
+ if (changed || settings.values['flutter.sdk'] != escapedRoot) {
+ settings.values['flutter.sdk'] = escapedRoot;
+ changed = true;
+ }
+ if (buildMode != null && settings.values['flutter.buildMode'] != buildMode) {
+ settings.values['flutter.buildMode'] = buildMode;
+ changed = true;
+ }
+
+ if (changed)
+ settings.writeContents(localProperties);
}
Future<Null> buildGradleProject(BuildMode buildMode, String target, String kernelPath) async {
- final File localProperties = ensureLocalProperties();
// Update the local.properties file with the build mode.
// FlutterPlugin v1 reads local.properties to determine build mode. Plugin v2
// uses the standard Android way to determine what to build, but we still
// update local.properties, in case we want to use it in the future.
final String buildModeName = getModeName(buildMode);
- final SettingsFile settings = new SettingsFile.parseFromFile(localProperties);
- settings.values['flutter.buildMode'] = buildModeName;
- settings.writeContents(localProperties);
+ updateLocalProperties(buildMode: buildModeName);
injectPlugins();
diff --git a/packages/flutter_tools/lib/src/base/utils.dart b/packages/flutter_tools/lib/src/base/utils.dart
index 342c967..fa17fb3 100644
--- a/packages/flutter_tools/lib/src/base/utils.dart
+++ b/packages/flutter_tools/lib/src/base/utils.dart
@@ -151,6 +151,8 @@
}
class SettingsFile {
+ SettingsFile();
+
SettingsFile.parse(String contents) {
for (String line in contents.split('\n')) {
line = line.trim();
diff --git a/packages/flutter_tools/lib/src/commands/create.dart b/packages/flutter_tools/lib/src/commands/create.dart
index 5d7e7a2..2e78dd3 100644
--- a/packages/flutter_tools/lib/src/commands/create.dart
+++ b/packages/flutter_tools/lib/src/commands/create.dart
@@ -6,6 +6,7 @@
import '../android/android.dart' as android;
import '../android/android_sdk.dart' as android_sdk;
+import '../android/gradle.dart' as gradle;
import '../base/common.dart';
import '../base/file_system.dart';
import '../base/utils.dart';
@@ -121,6 +122,9 @@
if (argResults['pub'])
await pubGet(directory: dirPath);
+ if (android_sdk.androidSdk != null)
+ gradle.updateLocalProperties(projectPath: dirPath);
+
appPath = fs.path.join(dirPath, 'example');
final String androidPluginIdentifier = templateContext['androidIdentifier'];
final String exampleProjectName = projectName + '_example';
@@ -153,6 +157,9 @@
injectPlugins(directory: appPath);
}
+ if (android_sdk.androidSdk != null)
+ gradle.updateLocalProperties(projectPath: appPath);
+
printStatus('');
// Run doctor; tell the user the next steps.