skip to Main Content

Generate Signed App APK used to work flawlessly for an app of mine until… I upgraded Android Studio to 2024.1.1.

It still builds and runs perfectly when generating debug APK. However, when I attempt to generate a release APK, it builds successfully, but when the app is launched on the smartphone, it crashes immediately with this FATAL EXCEPTION:

 java.lang.LinkageError:
 Method void com.me.koalawoes.MyAppActivity.onCreate(android.os.Bundle)
 overrides final method in class Lcom/me/mylib/core/MyActivity;
 (declaration of 'com.me.koalawoes.MyAppActivity'
  appears in /data/app/~~sHPI9ai93DWU6FOp_edr9A==/com.me.koalawoes-8LbG6dXPeAvMUDEvK-x8jQ==/base.apk)

But…MyActivity’s onCreate is not declared final at all:

    @Override
    public void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);

What could I be missing?

2

Answers


  1. Chosen as BEST ANSWER

    Here is how I solved the issue:

    In the proguard.cfg of my library (where com/me/mylib/core/MyActivity is), I added the following:

    -keepnames class com.me.mylib.core.MyActivity {
        public void onCreate(android.os.Bundle);
    }
    

    I still wonder what in my upgrade process (without changing a single line of code) made Generate Signed App APK rely on this -keepnames requirement for onCreate(...). It used to work without this.

    At this point, I can only suspect the update from AGP version 8.4 to AGP version 8.5 which was prompted by the upgrade to AS 2024.1.1. R8 is known to change with AGP, as in the android.enableR8.fullMode=false case when migrating from AGP version 7.0.

    Also, I couldn't find anything related in Android Gradle plugin 8.5 release notes.


  2. What you could be missing is that an Android Studio version upgrade may trigger a chain reaction in the form of AGP version update > R8 version update.

    It is unclear what happened in your specific upgrade process but there are numerous reports in which a naive Android Studio upgrade led to significant time waste in an attempt to generate a non-crushable release APK:

    I suspect R8’s default value of android.enableR8.fullMode has to do with this.

    From the R8 FAQ:

    In non-compat mode, also called “full mode”, R8 performs more aggressive optimizations, meaning additional ProGuard configuration rules may be required.

    Full mode can be enabled by adding android.enableR8.fullMode=true in the gradle.properties file. The main differences compared to R8 compatibility mode are:

    • The default constructor (<init>()) is not implicitly kept when a
      class is kept.
    • The default constructor (<init>()) is not implicitly
      kept for types which are only used with ldc, instanceof or checkcast.
    • The enclosing classes of fields or methods that are matched by a
      -keepclassmembers rule are not implicitly considered to be instantiated. Classes that are only instantiated using reflection
      should be kept explicitly with a -keep rule.
    • Default methods are not implicitly kept as abstract methods.
    • Attributes (such as Signature)
      and annotations are only kept for classes, methods and fields which
      are matched by keep rules even when -keepattributes is specified. The
      weakest rule that will keep annotations and attributes is
      -keep[classmembers],allowshrinking,allowoptimization,allowobfuscation,allowaccessmodification
      class-specification Additionally, for attributes describing a
      relationship such as InnerClass and EnclosingMethod, non-compat mode
      requires both endpoints being kept.
    • When optimizing or minifying the
      SourceFile attribute will always be rewritten to SourceFile unless
      -renamesourcefileattribute is used in which case the provided value is used. The original source file name is in the mapping file and
      when optimizing or minifying a mapping file is always produced.

    Note: android.enableR8.fullMode=true became default in AGP 8.0, not 8.5 and certainly not in 7.0. So this alone cannot explain what you described. Citation: https://developer.android.com/build/releases/past-releases/agp-8-0-0-release-notes#default-changes

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search