fix(android): guard getLongVersionCode() for API < 28 to prevent launch crash#219
Open
FeodorFitsner wants to merge 1 commit into
Open
fix(android): guard getLongVersionCode() for API < 28 to prevent launch crash#219FeodorFitsner wants to merge 1 commit into
FeodorFitsner wants to merge 1 commit into
Conversation
…ch crash getAppVersion runs on every startup and called PackageInfo.getLongVersionCode() (API 28+) unconditionally. R8 outlines the call into a synthetic class it may merge with other API 28+ outlines (e.g. Flutter 3.41's ImageDecoder-based image decoder); invoking that class on API < 28 fails verification with NoClassDefFoundError (android.graphics.ImageDecoder$OnHeaderDecodedListener) and crashes the app on launch on Android 8.1 and below. Guard the call with Build.VERSION.SDK_INT and fall back to the deprecated versionCode int field on older devices.
Open
1 task
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Flet/serious_python apps crash on launch on Android 8.1 and below (API < 28), while working on Android 9+ (API 28+). Reported in flet-dev/flet#6619 as a regression that started in Flet 0.81.0.
Root cause
AndroidPlugin.getAppVersion— whichserious_pythoncalls on every app startup (to build the site-packages cache-invalidation key, before Python starts) — callsPackageInfo.getLongVersionCode(), which is API 28+, unconditionally.R8 (release builds) outlines API-28 calls into a synthetic class (
AndroidPlugin$$ExternalSyntheticApiModelOutline0) and horizontally merges into it the API-28 outlines from other code — notably Flutter 3.41's newio.flutter.embedding.engine.image.ImageDecoderDefaultImpl(which usesandroid.graphics.ImageDecoder). Invoking the version-code outline on API < 28 forces that merged class to load/verify, and its references toandroid.graphics.ImageDecoder$OnHeaderDecodedListener(API 28) fail to resolve:→ uncaught on the platform-channel handler → app crash.
This explains the exact regression boundary: Flet 0.80.5 shipped Flutter 3.38.7 (no
ImageDecoderDefaultImpl); Flet 0.81.0 bumped to Flutter 3.41.2, which added it. The unguardedgetLongVersionCode()was always present but only became fatal once Flutter contributed anImageDecoderoutline for R8 to merge with.Fix
Guard the call with
Build.VERSION.SDK_INTand fall back to the deprecatedversionCodeint field on API < 28. The API-26 path then never invokes the outlined method, so the merged synthetic class is never loaded on old devices (it's only loaded lazily on first invocation).Verification
Reproduced and verified on Android emulators with a stock
flet createcounter app (Flet 0.85.3 / Flutter 3.41.7, release APK):Deobfuscated the release
mapping.txtto confirm the merged outline class contained bothgetLongVersionCode(PackageInfo)and theImageDecodermethods.Fixes flet-dev/flet#6619.