Skip to content

Commit 7851a75

Browse files
Fix NPE in flutter tools (flutter#34725)
1 parent 0d4f4bd commit 7851a75

File tree

2 files changed

+21
-7
lines changed

2 files changed

+21
-7
lines changed

packages/flutter_tools/lib/src/android/gradle.dart

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -509,7 +509,7 @@ Future<void> _buildGradleProjectV2(
509509
flutterUsage.sendTiming('build', 'gradle-v2', Duration(milliseconds: sw.elapsedMilliseconds));
510510

511511
if (!isBuildingBundle) {
512-
final Iterable<File> apkFiles = _findApkFiles(project, androidBuildInfo);
512+
final Iterable<File> apkFiles = findApkFiles(project, androidBuildInfo);
513513
if (apkFiles.isEmpty)
514514
throwToolExit('Gradle build failed to produce an Android package.');
515515
// Copy the first APK to app.apk, so `flutter run`, `flutter install`, etc. can find it.
@@ -546,32 +546,33 @@ Future<void> _buildGradleProjectV2(
546546
}
547547
}
548548

549-
Iterable<File> _findApkFiles(GradleProject project, AndroidBuildInfo androidBuildInfo) {
549+
@visibleForTesting
550+
Iterable<File> findApkFiles(GradleProject project, AndroidBuildInfo androidBuildInfo) {
550551
final Iterable<String> apkFileNames = project.apkFilesFor(androidBuildInfo);
551552
if (apkFileNames.isEmpty)
552553
return const <File>[];
553554

554-
return apkFileNames.map<File>((String apkFileName) {
555+
return apkFileNames.expand<File>((String apkFileName) {
555556
File apkFile = project.apkDirectory.childFile(apkFileName);
556557
if (apkFile.existsSync())
557-
return apkFile;
558+
return <File>[apkFile];
558559
final BuildInfo buildInfo = androidBuildInfo.buildInfo;
559560
final String modeName = camelCase(buildInfo.modeName);
560561
apkFile = project.apkDirectory
561562
.childDirectory(modeName)
562563
.childFile(apkFileName);
563564
if (apkFile.existsSync())
564-
return apkFile;
565+
return <File>[apkFile];
565566
if (buildInfo.flavor != null) {
566567
// Android Studio Gradle plugin v3 adds flavor to path.
567568
apkFile = project.apkDirectory
568569
.childDirectory(buildInfo.flavor)
569570
.childDirectory(modeName)
570571
.childFile(apkFileName);
571572
if (apkFile.existsSync())
572-
return apkFile;
573+
return <File>[apkFile];
573574
}
574-
return null;
575+
return const <File>[];
575576
});
576577
}
577578

packages/flutter_tools/test/android/gradle_test.dart

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,18 @@ void main() {
4141
expect(shouldBeToolExit, isToolExit);
4242
});
4343

44+
// Regression test for https://github.com/flutter/flutter/issues/34700
45+
testUsingContext('Does not return nulls in apk list', () {
46+
final GradleProject gradleProject = MockGradleProject();
47+
const AndroidBuildInfo buildInfo = AndroidBuildInfo(BuildInfo.debug);
48+
when(gradleProject.apkFilesFor(buildInfo)).thenReturn(<String>['not_real']);
49+
when(gradleProject.apkDirectory).thenReturn(fs.currentDirectory);
50+
51+
expect(findApkFiles(gradleProject, buildInfo), <File>[]);
52+
}, overrides: <Type, Generator>{
53+
FileSystem: () => MemoryFileSystem(),
54+
});
55+
4456
test('androidXFailureRegex should match lines with likely AndroidX errors', () {
4557
final List<String> nonMatchingLines = <String>[
4658
':app:preBuild UP-TO-DATE',
@@ -537,3 +549,4 @@ Platform fakePlatform(String name) {
537549
class MockLocalEngineArtifacts extends Mock implements LocalEngineArtifacts {}
538550
class MockProcessManager extends Mock implements ProcessManager {}
539551
class MockXcodeProjectInterpreter extends Mock implements XcodeProjectInterpreter {}
552+
class MockGradleProject extends Mock implements GradleProject {}

0 commit comments

Comments
 (0)