Question

LinkageError: Method onCreate overrides final method

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?

 4  109  4
1 Jan 1970

Solution

 2

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.

2024-06-30
ususer

Solution

 1

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 initially suspected R8's default value of android.enableR8.fullMode has to do with this, but...

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

2024-07-02
WebViewer