// Copyright 2014 The Flutter Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. import 'package:file/file.dart'; import '../../src/common.dart'; import '../test_utils.dart'; import 'project.dart'; class MultidexProject extends Project { MultidexProject(this.includeFlutterMultiDexApplication); @override Future setUpIn(Directory dir, { bool useDeferredLoading = false, bool useSyntheticPackage = false, }) { this.dir = dir; if (androidSettings != null) { writeFile(fileSystem.path.join(dir.path, 'android', 'settings.gradle'), androidSettings); } if (androidBuild != null) { writeFile(fileSystem.path.join(dir.path, 'android', 'build.gradle'), androidBuild); } if (androidLocalProperties != null) { writeFile(fileSystem.path.join(dir.path, 'android', 'local.properties'), androidLocalProperties); } if (androidGradleProperties != null) { writeFile(fileSystem.path.join(dir.path, 'android', 'gradle.properties'), androidGradleProperties); } if (appBuild != null) { writeFile(fileSystem.path.join(dir.path, 'android', 'app', 'build.gradle'), appBuild); } if (appManifest != null) { writeFile(fileSystem.path.join(dir.path, 'android', 'app', 'src', 'main', 'AndroidManifest.xml'), appManifest); } if (appStrings != null) { writeFile(fileSystem.path.join(dir.path, 'android', 'app', 'src', 'main', 'res', 'values', 'strings.xml'), appStrings); } if (appStyles != null) { writeFile(fileSystem.path.join(dir.path, 'android', 'app', 'src', 'main', 'res', 'values', 'styles.xml'), appStyles); } if (appLaunchBackground != null) { writeFile(fileSystem.path.join(dir.path, 'android', 'app', 'src', 'main', 'res', 'drawable', 'launch_background.xml'), appLaunchBackground); } if (includeFlutterMultiDexApplication && appMultidexApplication != null) { writeFile(fileSystem.path.join(dir.path, 'android', 'app', 'src', 'main', 'java', fileSystem.path.join('io', 'flutter', 'app', 'FlutterMultiDexApplication.java')), appMultidexApplication); } return super.setUpIn(dir); } final bool includeFlutterMultiDexApplication; @override final String pubspec = ''' name: test environment: sdk: ">=2.12.0-0 <3.0.0" dependencies: flutter: sdk: flutter # Pin to specific plugin versions to avoid out-of-band failures. cloud_firestore: 2.5.3 firebase_core: 1.6.0 '''; @override final String main = r''' import 'package:flutter/material.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', home: Container(), ); } } '''; String get androidSettings => r''' include ':app' def localPropertiesFile = new File(rootProject.projectDir, "local.properties") def properties = new Properties() assert localPropertiesFile.exists() localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } def flutterSdkPath = properties.getProperty("flutter.sdk") assert flutterSdkPath != null, "flutter.sdk not set in local.properties" apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" '''; String get androidBuild => r''' buildscript { ext.kotlin_version = '1.3.50' repositories { google() mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:4.1.0' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } allprojects { repositories { google() mavenCentral() } } rootProject.buildDir = '../build' subprojects { project.buildDir = "${rootProject.buildDir}/${project.name}" } subprojects { project.evaluationDependsOn(':app') } task clean(type: Delete) { delete rootProject.buildDir } '''; String get appBuild => r''' def localProperties = new Properties() def localPropertiesFile = rootProject.file('local.properties') if (localPropertiesFile.exists()) { localPropertiesFile.withReader('UTF-8') { reader -> localProperties.load(reader) } } def flutterRoot = localProperties.getProperty('flutter.sdk') if (flutterRoot == null) { throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") } def flutterVersionCode = localProperties.getProperty('flutter.versionCode') if (flutterVersionCode == null) { flutterVersionCode = '1' } def flutterVersionName = localProperties.getProperty('flutter.versionName') if (flutterVersionName == null) { flutterVersionName = '1.0' } apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { compileSdkVersion 31 compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } kotlinOptions { jvmTarget = '1.8' } sourceSets { main.java.srcDirs += 'src/main/kotlin' } defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "com.example.multidextest2" minSdkVersion 16 targetSdkVersion 30 versionCode flutterVersionCode.toInteger() versionName flutterVersionName } buildTypes { release { // TODO: Add your own signing config for the release build. // Signing with the debug keys for now, so `flutter run --release` works. signingConfig signingConfigs.debug } } } flutter { source '../..' } dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" } '''; String get androidLocalProperties => ''' flutter.sdk=${getFlutterRoot()} flutter.buildMode=debug flutter.versionName=1.0.0 flutter.versionCode=22 '''; String get androidGradleProperties => ''' org.gradle.jvmargs=-Xmx1536M android.useAndroidX=true android.enableJetifier=true android.enableR8=true android.experimental.enableNewResourceShrinker=true '''; String get appManifest => r''' '''; String get appStrings => r''' '''; String get appStyles => r''' '''; String get appLaunchBackground => r''' '''; String get appMultidexApplication => r''' // Generated file. // // If you wish to remove Flutter's multidex support, delete this entire file. // // Modifications to this file should be done in a copy under a different name // as this file may be regenerated. package io.flutter.app; import android.app.Application; import android.content.Context; import androidx.annotation.CallSuper; import androidx.multidex.MultiDex; /** * Extension of {@link android.app.Application}, adding multidex support. */ public class FlutterMultiDexApplication extends Application { @Override @CallSuper protected void attachBaseContext(Context base) { super.attachBaseContext(base); MultiDex.install(this); } } '''; }