Migrate Android build scripts to Kotlin DSL (#58)

Replaces Groovy-based Gradle files with Kotlin DSL equivalents for build.gradle, settings.gradle, and app/build.gradle. Updates AndroidManifest.xml to add taskAffinity and queries for PROCESS_TEXT intent. Refactors MainActivity.kt for cleaner syntax. Increases Gradle JVM memory settings and updates Gradle wrapper and plugin versions for improved build performance and compatibility.
This commit is contained in:
Feodor Fitsner 2025-11-27 17:12:15 -08:00 committed by GitHub
parent 1a928b53b4
commit 4c63345e28
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 170 additions and 159 deletions

View File

@ -1,105 +0,0 @@
plugins {
id "com.android.application"
id "org.jetbrains.kotlin.android"
id "dev.flutter.flutter-gradle-plugin"
}
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader('UTF-8') { reader ->
localProperties.load(reader)
}
}
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
}
def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
flutterVersionName = '1.0'
}
android {
namespace "{{ cookiecutter.org_name_2 }}.{{ cookiecutter.package_name }}"
compileSdkVersion flutter.compileSdkVersion
packagingOptions {
jniLibs {
useLegacyPackaging true
}
doNotStrip "*/arm64-v8a/libpython*.so"
doNotStrip "*/armeabi-v7a/libpython*.so"
doNotStrip "*/x86/libpython*.so"
doNotStrip "*/x86_64/libpython*.so"
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = '17'
}
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
{% set min_sdk_version = get_pyproject("tool.flet.android.min_sdk_version") %}
{% set target_sdk_version = get_pyproject("tool.flet.android.target_sdk_version") %}
defaultConfig {
applicationId "{{ cookiecutter.org_name_2 }}.{{ cookiecutter.package_name }}"
minSdkVersion {{ min_sdk_version if min_sdk_version else "flutter.minSdkVersion" }}
targetSdkVersion {{ target_sdk_version if target_sdk_version else "flutter.targetSdkVersion" }}
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
println("Gradle build config:")
println(" minSdkVersion: {{ min_sdk_version if min_sdk_version else "$flutter.minSdkVersion" }}")
println(" targetSdkVersion: {{ target_sdk_version if target_sdk_version else "$flutter.targetSdkVersion" }}")
println(" versionCode: $flutter.versionCode")
println(" versionName: $flutter.versionName")
// flet: split_per_abi {% if not cookiecutter.split_per_abi %}
ndk {
{% if cookiecutter.options.target_arch %}
abiFilters {% for arch in cookiecutter.options.target_arch %}'{{ arch }}'{% if not loop.last %}, {% endif %}{% endfor %}
{% else %}
abiFilters 'arm64-v8a', 'armeabi-v7a', 'x86_64'
{% endif %}
}
// flet: end of split_per_abi {% endif %}
}
// flet: android_signing {% if cookiecutter.options.android_signing %}
signingConfigs {
release {
keyAlias System.getenv('FLET_ANDROID_SIGNING_KEY_ALIAS')
keyPassword System.getenv('FLET_ANDROID_SIGNING_KEY_PASSWORD')
storeFile System.getenv('FLET_ANDROID_SIGNING_KEY_STORE') ? file(System.getenv('FLET_ANDROID_SIGNING_KEY_STORE')) : null
storePassword System.getenv('FLET_ANDROID_SIGNING_KEY_STORE_PASSWORD')
}
}
// flet: end of android_signing {% endif %}
buildTypes {
release {
// flet: android_signing {% if cookiecutter.options.android_signing %}
signingConfig signingConfigs.release
// {% else %}
signingConfig signingConfigs.debug
// flet: end of android_signing {% endif %}
}
}
}
flutter {
source '../..'
}
dependencies {}

View File

@ -0,0 +1,103 @@
import java.util.Properties
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
// The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
id("dev.flutter.flutter-gradle-plugin")
}
val localProperties = Properties().apply {
val localPropertiesFile = rootProject.file("local.properties")
if (localPropertiesFile.exists()) {
localPropertiesFile.inputStream().use { load(it) }
}
}
val flutterVersionCode = localProperties.getProperty("flutter.versionCode")?.toIntOrNull() ?: 1
val flutterVersionName = localProperties.getProperty("flutter.versionName") ?: "1.0"
android {
namespace = "{{ cookiecutter.org_name_2 }}.{{ cookiecutter.package_name }}"
compileSdk = flutter.compileSdkVersion
ndkVersion = flutter.ndkVersion
packaging {
jniLibs {
useLegacyPackaging = true
keepDebugSymbols += listOf(
"*/arm64-v8a/libpython*.so",
"*/armeabi-v7a/libpython*.so",
"*/x86/libpython*.so",
"*/x86_64/libpython*.so",
)
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = JavaVersion.VERSION_17.toString()
}
sourceSets["main"].java.srcDir("src/main/kotlin")
{% set min_sdk_version = get_pyproject("tool.flet.android.min_sdk_version") %}
{% set target_sdk_version = get_pyproject("tool.flet.android.target_sdk_version") %}
defaultConfig {
applicationId = "{{ cookiecutter.org_name_2 }}.{{ cookiecutter.package_name }}"
val resolvedMinSdk = {{ min_sdk_version if min_sdk_version else "flutter.minSdkVersion" }}
minSdk = resolvedMinSdk
val resolvedTargetSdk = {{ target_sdk_version if target_sdk_version else "flutter.targetSdkVersion" }}
targetSdk = resolvedTargetSdk
versionCode = flutterVersionCode
versionName = flutterVersionName
println("Gradle build config:")
println(" minSdkVersion: $resolvedMinSdk")
println(" targetSdkVersion: $resolvedTargetSdk")
println(" versionCode: $flutterVersionCode")
println(" versionName: $flutterVersionName")
// flet: split_per_abi {% if not cookiecutter.split_per_abi %}
ndk {
{% if cookiecutter.options.target_arch %}
abiFilters += listOf({% for arch in cookiecutter.options.target_arch %}"{{ arch }}"{% if not loop.last %}, {% endif %}{% endfor %})
{% else %}
abiFilters += listOf("arm64-v8a", "armeabi-v7a", "x86_64")
{% endif %}
}
// flet: end of split_per_abi {% endif %}
}
// flet: android_signing {% if cookiecutter.options.android_signing %}
signingConfigs {
create("release") {
keyAlias = System.getenv("FLET_ANDROID_SIGNING_KEY_ALIAS")
keyPassword = System.getenv("FLET_ANDROID_SIGNING_KEY_PASSWORD")
storeFile = System.getenv("FLET_ANDROID_SIGNING_KEY_STORE")?.let { file(it) }
storePassword = System.getenv("FLET_ANDROID_SIGNING_KEY_STORE_PASSWORD")
}
}
// flet: end of android_signing {% endif %}
buildTypes {
release {
// flet: android_signing {% if cookiecutter.options.android_signing %}
signingConfig = signingConfigs.getByName("release")
// {% else %}
signingConfig = signingConfigs.getByName("debug")
// flet: end of android_signing {% endif %}
}
}
}
flutter {
source = "../.."
}
dependencies {}

View File

@ -23,6 +23,7 @@
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:taskAffinity=""
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
@ -57,4 +58,15 @@
android:name="flutterEmbedding"
android:value="2" />
</application>
</manifest>
<!-- Required to query activities that can process text, see:
https://developer.android.com/training/package-visibility and
https://developer.android.com/reference/android/content/Intent#ACTION_PROCESS_TEXT.
In particular, this is used by the Flutter engine in io.flutter.plugin.text.ProcessTextPlugin. -->
<queries>
<intent>
<action android:name="android.intent.action.PROCESS_TEXT" />
<data android:mimeType="text/plain" />
</intent>
</queries>
</manifest>

View File

@ -2,5 +2,4 @@ package {{ cookiecutter.org_name_2 }}.{{ cookiecutter.package_name }}
import io.flutter.embedding.android.FlutterActivity
class MainActivity: FlutterActivity() {
}
class MainActivity : FlutterActivity()

View File

@ -1,18 +0,0 @@
allprojects {
repositories {
google()
mavenCentral()
}
}
rootProject.buildDir = '../build'
subprojects {
project.buildDir = "${rootProject.buildDir}/${project.name}"
}
subprojects {
project.evaluationDependsOn(':app')
}
tasks.register("clean", Delete) {
delete rootProject.buildDir
}

View File

@ -0,0 +1,24 @@
allprojects {
repositories {
google()
mavenCentral()
}
}
val newBuildDir: Directory =
rootProject.layout.buildDirectory
.dir("../../build")
.get()
rootProject.layout.buildDirectory.value(newBuildDir)
subprojects {
val newSubprojectBuildDir: Directory = newBuildDir.dir(project.name)
project.layout.buildDirectory.value(newSubprojectBuildDir)
}
subprojects {
project.evaluationDependsOn(":app")
}
tasks.register<Delete>("clean") {
delete(rootProject.layout.buildDirectory)
}

View File

@ -1,3 +1,2 @@
org.gradle.jvmargs=-Xmx4G -XX:MaxMetaspaceSize=2G -XX:+HeapDumpOnOutOfMemoryError
org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError
android.useAndroidX=true
android.enableJetifier=true

View File

@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-all.zip

View File

@ -1,30 +0,0 @@
pluginManagement {
def flutterSdkPath = {
def properties = new Properties()
file("local.properties").withInputStream { properties.load(it) }
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
return flutterSdkPath
}
settings.ext.flutterSdkPath = flutterSdkPath()
includeBuild("${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle")
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
plugins {
id "dev.flutter.flutter-gradle-plugin" version "1.0.0" apply false
}
}
plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version "8.6.1" apply false
id "org.jetbrains.kotlin.android" version "2.1.0" apply false
}
include ":app"

View File

@ -0,0 +1,27 @@
pluginManagement {
val flutterSdkPath =
run {
val properties = java.util.Properties()
file("local.properties").inputStream().use { properties.load(it) }
val flutterSdkPath = properties.getProperty("flutter.sdk")
require(flutterSdkPath != null) { "flutter.sdk not set in local.properties" }
flutterSdkPath
}
settings.extra["flutterSdkPath"] = flutterSdkPath
includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}
plugins {
id("dev.flutter.flutter-plugin-loader") version "1.0.0"
id("com.android.application") version "8.11.1" apply false
id("org.jetbrains.kotlin.android") version "2.2.20" apply false
}
include(":app")