| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145 |
- import java.io.FileInputStream
- import java.util.Properties
- plugins {
- id("com.android.application")
- // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
- id("dev.flutter.flutter-gradle-plugin")
- }
- // 发布签名凭据放在 android/key.properties(和 mathtool2 同一套)。
- // 该文件和 key.jks 都已被 android/.gitignore 忽略,不会进仓库。
- val keystorePropertiesFile = rootProject.file("key.properties")
- val keystoreProperties = Properties()
- if (keystorePropertiesFile.exists()) {
- keystoreProperties.load(FileInputStream(keystorePropertiesFile))
- }
- android {
- namespace = "com.nonvioce.cal"
- compileSdk = flutter.compileSdkVersion
- compileOptions {
- sourceCompatibility = JavaVersion.VERSION_17
- targetCompatibility = JavaVersion.VERSION_17
- // Symja 使用 java.time(API 26 才有);minSdk 24 必须开 desugaring。
- // 注意:Ijs 在这一点上是错的(minSdk 24 却没开),这里顺手修掉。
- isCoreLibraryDesugaringEnabled = true
- }
- defaultConfig {
- applicationId = "com.nonvioce.cal"
- minSdk = 24
- targetSdk = flutter.targetSdkVersion
- versionCode = flutter.versionCode
- versionName = flutter.versionName
- // 光 Symja 就有约 42k 方法,必须 multiDex
- multiDexEnabled = true
- }
- signingConfigs {
- // 只有拿到凭据才建这个配置;否则下面的 release 退回调试签名,
- // 保证"没带 key.properties 的机器"上依然能构建。
- if (keystorePropertiesFile.exists()) {
- create("release") {
- keyAlias = keystoreProperties.getProperty("keyAlias")
- keyPassword = keystoreProperties.getProperty("keyPassword")
- storeFile = file(keystoreProperties.getProperty("storeFile"))
- storePassword = keystoreProperties.getProperty("storePassword")
- }
- }
- }
- buildTypes {
- release {
- signingConfig = if (keystorePropertiesFile.exists()) {
- signingConfigs.getByName("release")
- } else {
- signingConfigs.getByName("debug")
- }
- // 【真机实测的结论】不要对 Symja 开 R8 混淆。
- // Symja 及其依赖大量用「类名字符串」做反射创建,R8 看不到引用关系就会改名,
- // 运行时按原名找不到 -> 静态初始化直接炸。实测踩到两个:
- // 1. log4j2-android 的 com.celeral.android.logging.log4j.AndroidLoggerContextFactory
- // (由 system property "log4j2.loggerContextFactory" 指定)
- // 2. apfloat 的 org.apfloat.internal.LongBuilderFactory(由 "builderFactory" 属性指定)
- // -> F.<clinit> 抛 ExceptionInInitializerError
- // 官方的 Symja Android 参考工程 axkr/symja-example 同样不开 minify。
- // proguard-rules.pro 里的 -keep 规则保留着,将来若要重新开混淆可以从那里起步,
- // 但必须先在真机上回归。
- isMinifyEnabled = false
- isShrinkResources = false
- proguardFiles(
- getDefaultProguardFile("proguard-android-optimize.txt"),
- "proguard-rules.pro",
- )
- }
- }
- packaging {
- resources {
- excludes += setOf(
- "META-INF/DEPENDENCIES",
- "META-INF/LICENSE",
- "META-INF/LICENSE.txt",
- "META-INF/license.txt",
- "META-INF/NOTICE",
- "META-INF/NOTICE.txt",
- "META-INF/notice.txt",
- "META-INF/ASL2.0",
- "META-INF/*.kotlin_module",
- "Log4j2Plugins.dat",
- )
- pickFirsts += setOf(
- "**/*.xsd",
- )
- }
- // 只留 arm64-v8a 的原生库。
- //
- // 另外两条路都试过、都不行:
- // · defaultConfig 里写 ndk.abiFilters —— 实测三个 ABI 的 libflutter.so 照样全进包
- // · android/gradle.properties 里写 target-platform —— flutter_tools 会显式传
- // -Ptarget-platform=... (gradle.dart:581),命令行参数盖过 gradle.properties
- // 这里在 APK 组装阶段剔目录,Flutter 就管不着了。
- jniLibs {
- excludes += setOf(
- "lib/armeabi-v7a/**",
- "lib/x86/**",
- "lib/x86_64/**",
- )
- }
- }
- }
- kotlin {
- compilerOptions {
- jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17
- }
- }
- dependencies {
- coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.1.5")
- implementation("org.matheclipse:matheclipse-core:3.2.0")
- // log4j-api 在 Android 上需要一个实现,否则 Symja 的日志路径会抛错
- runtimeOnly("com.celeral:log4j2-android:1.0.0")
- // 用 Android 变体的 guava,避免 JRE 专属类(java.beans 等)
- implementation("com.google.guava:guava:33.5.0-android")
- // MCP 服务器用的内嵌 HTTP 服务器(JSON-RPC over HTTP)
- implementation("org.nanohttpd:nanohttpd:2.3.1")
- }
- configurations.all {
- resolutionStrategy {
- force("com.google.guava:guava:33.5.0-android")
- }
- }
- flutter {
- source = "../.."
- }
|