Bug fixes
- Fix every
flet_adscontrol (BannerAd,InterstitialAd,NativeAd,ConsentManager) crashing on construction withRuntimeError: <Ad>(N) Control must be added to the page first, which made the package unusable since 0.85. The mobile-only platform guard readself.pagefrominit(), which runs at construction — before the control is attached to the page — so the parent-chain lookup raised. The guard is back inbefore_update(), a post-mount hook whereself.pageresolves, so ads construct freely and only reject web/desktop at mount time (#6726, #6735) by @ndonkoHenri.
Improvements
-
An Android permission set to
falseis now actively removed from the merged manifest instead of merely being left out of the generated one. Gradle's manifest merger folds in the manifest of every Flutter plugin and can also synthesize permissions on its own, andfalsepreviously had no effect on either — the template only skipped emitting the entry, so a plugin-contributed permission passed straight through with no way to stop it. Concretely:flet-camerapulls incamera_android_camerax, which declaresWRITE_EXTERNAL_STORAGEbounded tomaxSdkVersion="28", and the merger implies an unboundedREAD_EXTERNAL_STORAGEfrom it (legacy behaviour — write once implied read). Both then appear in the Play Console despite being absent frompyproject.toml, and the unbounded read is exactly the shape Google Play's storage policy objects to. Permissions set tofalsenow render as<uses-permission android:name="…" tools:node="remove" />(the template's<manifest>gained thetoolsnamespace), which strips them during the merge; removing a permission nothing declares is a harmless no-op. Verified on Flet Studio: 11 permissions down to 9, both storage entries gone from the built APK by @FeodorFitsner. -
Bumped
serious_pythonto 4.5.1 and re-pinned the bundled python-build snapshot to 20260730 (dart_bridge1.7.1).serious_python4.5.1 tracks the same python-build release, keepingPYTHON_BUILD_RELEASE_DATEin sync with itspythonReleaseDateas the pin requires by @FeodorFitsner. -
Android ProGuard/R8 rules can now be extended from
pyproject.tomlvia[tool.flet.android].proguard_rules. The generated project'sandroid/app/proguard-rules.prowas a fixed template file, so an app that needed an extra keep rule had no way to add one short of downloading the published build template, patching the file and passing--template. This matters for Pyjnius:autoclass()resolves Java classes by name at runtime, and R8 renames anything in the APK that isn't kept — soautoclass()on a class bundled by a Flutter plugin or by your own Java/Kotlin fails in release builds. It fails hard: JNIFindClassreturns null and the process aborts withJNI DETECTED ERROR IN APPLICATION: obj == null/SIGABRTrather than raising a catchable Python exception, and because R8 only runs in release builds it never reproduces in debug. Android framework classes (android.os.Buildand friends) live outside the APK and never needed a rule. Rules are appended to the defaults, since R8 has no directive that undoes a keep; to remove the defaults instead — in particular-keepnames class * { *; }, which keeps every class and member name in the app and costs 2.5 MB ofclasses.dexon Flet Studio (5.9 MB → 3.4 MB, -43%) — set[tool.flet.android].proguard_default_rules = false. Dropping the defaults is safe for Pyjnius'sPythonActivityaccess, becauseserious_python_android4.1.0+ ships that keep rule in its ownconsumer-rules.pro. Defaults are unchanged, so existing builds render exactly the same file by @FeodorFitsner. -
Android Gradle properties can now be configured from
pyproject.tomlvia[tool.flet.android.gradle_properties]. The generated project'sandroid/gradle.propertieswas previously fixed, so its memory settings —org.gradle.jvmargs=-Xmx8Gplus a 4 GB metaspace — could not be changed. That is larger than the total RAM of a standard GitHub-hosted runner (measured: 7.8 GB with 3 GB of swap), so release builds, which additionally run Dart AOT once per ABI and R8, could exhaust memory and stall with no error; the only workaround was to download the published build template, patch the file and pass--template. Entries in the table override the defaults or add new properties, e.g."org.gradle.jvmargs" = "-Xmx3G -XX:MaxMetaspaceSize=1G"and"org.gradle.workers.max" = 2. Defaults are unchanged, so existing builds render exactly the same file by @FeodorFitsner.
Full Changelog: v0.86.4...v0.86.5