kanyun-inc / Kace

Kace: Kotlin Android Compatible Extensions, a framework for assisting in the seamless migration from kotlin-android-extensions
Apache License 2.0
261 stars 11 forks source link

java.lang.AbstractMethodError: abstract method "void androidx.lifecycle.DefaultLifecycleObserver.onCreate #13

Closed CodeIdeal closed 1 year ago

CodeIdeal commented 1 year ago

目前项目因为第三方以依赖的原因,agp被固定在了4.2.0,我们从kotlin1.4.2升级到kotlin1.7.20的时候,编译能够通过,但是运行时会报如下错误:

18:18:51.775  W  java.lang.AbstractMethodError: abstract method "void androidx.lifecycle.DefaultLifecycleObserver.onCreate(androidx.lifecycle.LifecycleOwner)"
18:18:51.775  W     at androidx.lifecycle.FullLifecycleObserverAdapter.onStateChanged(FullLifecycleObserverAdapter.java:36)
18:18:51.775  W     at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry.java:354)
18:18:51.775  W     at androidx.lifecycle.LifecycleRegistry.addObserver(LifecycleRegistry.java:196)
18:18:51.775  W     at com.kanyun.kace.AndroidExtensionsActivity.<init>(AndroidExtensionsComponent.kt:47)
18:18:51.775  W     at com.kanyun.kace.AndroidExtensionsComponentKt.AndroidExtensionsComponent(AndroidExtensionsComponent.kt:34)
18:18:51.775  W     at com.kanyun.kace.AndroidExtensionsImpl.initComponent(AndroidExtensionsImpl.kt:29)
18:18:51.775  W     at com.kanyun.kace.AndroidExtensionsImpl.findViewByIdCached(AndroidExtensionsImpl.kt:40)
18:18:51.775  W     at com.tvbc.mddtv.base.TvBaseActivity.findViewByIdCached(TvBaseActivity.kt)

也看了下apk中DefaultLifecycleObserver反编译的结果:

package androidx.lifecycle;

/* loaded from: classes.dex */
public interface DefaultLifecycleObserver extends FullLifecycleObserver {
    @Override // androidx.lifecycle.FullLifecycleObserver
    void onCreate(LifecycleOwner lifecycleOwner);

    @Override // androidx.lifecycle.FullLifecycleObserver
    void onDestroy(LifecycleOwner lifecycleOwner);

    @Override // androidx.lifecycle.FullLifecycleObserver
    void onPause(LifecycleOwner lifecycleOwner);

    @Override // androidx.lifecycle.FullLifecycleObserver
    void onResume(LifecycleOwner lifecycleOwner);

    @Override // androidx.lifecycle.FullLifecycleObserver
    void onStart(LifecycleOwner lifecycleOwner);

    @Override // androidx.lifecycle.FullLifecycleObserver
    void onStop(LifecycleOwner lifecycleOwner);

    /* renamed from: androidx.lifecycle.DefaultLifecycleObserver$-CC  reason: invalid class name */
    /* loaded from: classes.dex */
    public final /* synthetic */ class CC {
        public static void $default$onCreate(DefaultLifecycleObserver _this, LifecycleOwner owner) {
        }

        public static void $default$onStart(DefaultLifecycleObserver _this, LifecycleOwner owner) {
        }

        public static void $default$onResume(DefaultLifecycleObserver _this, LifecycleOwner owner) {
        }

        public static void $default$onPause(DefaultLifecycleObserver _this, LifecycleOwner owner) {
        }

        public static void $default$onStop(DefaultLifecycleObserver _this, LifecycleOwner owner) {
        }

        public static void $default$onDestroy(DefaultLifecycleObserver _this, LifecycleOwner owner) {
        }
    }
}

感觉像是 java8的 interface default method的问题,但也不太确定。 目前就想到一个解决办法,就是把AndroidExtensionsActivity中的DefaultLifecycleObserver匿名内部类的所有方法都重写。 如果能方便改一下的话不胜感激。

bennyhuo commented 1 year ago

Kace runtime 编译的时候 compileOnly 了 androidx lifecycle 2.4.0,看来是版本兼容导致的。

CodeIdeal commented 1 year ago

我这边项目依赖的是lifecycle-common-java8 2.2.0版本。我试了下把lifecycle-common-java8 2.2.0依赖换成了lifecycle-common 2.4.0依旧还是有这个问题。

CodeIdeal commented 1 year ago

我在自己项目的activity中添加相同的使用DefaultLifecycleObserver的代码却并不会报错。 然后对比了下反编译后的代码异同,发现kace runtime的代码反编译之后DefaultLifecycleObserver的匿名实现并没有重写所有的default空方法。 kace runtime代码反编译后的代码如下:

    public AndroidExtensionsActivity(Activity activity, final Function0<Unit> onDestroy) {
        Intrinsics.checkNotNullParameter(activity, "activity");
        Intrinsics.checkNotNullParameter(onDestroy, "onDestroy");
        this.activity = activity;
        if (!(activity instanceof LifecycleOwner)) {
            return;
        }
        ((LifecycleOwner) activity).getLifecycle().addObserver(new DefaultLifecycleObserver() { // from class: com.kanyun.kace.AndroidExtensionsActivity.1
            @Override // androidx.lifecycle.DefaultLifecycleObserver, androidx.lifecycle.FullLifecycleObserver
            public void onDestroy(LifecycleOwner owner) {
                Intrinsics.checkNotNullParameter(owner, "owner");
                super.onDestroy(owner);
                onDestroy.invoke();
            }
        });
    }

下面是我在自己项目的activity中使用DefaultLifecycleObserver后反编译的结果:

@Override // *.*.*.*.*BaseActivity
protected void onInit(Bundle savedInstanceState) {
    getLifecycle().addObserver(new DefaultLifecycleObserver() { // from class: *.*.*.*.*Activity$onInit$1
        @Override // androidx.lifecycle.DefaultLifecycleObserver, androidx.lifecycle.FullLifecycleObserver
        public /* synthetic */ void onCreate(LifecycleOwner lifecycleOwner) {
            DefaultLifecycleObserver.CC.$default$onCreate(this, lifecycleOwner);
        }

        @Override // androidx.lifecycle.DefaultLifecycleObserver, androidx.lifecycle.FullLifecycleObserver
        public /* synthetic */ void onDestroy(LifecycleOwner lifecycleOwner) {
            DefaultLifecycleObserver.CC.$default$onDestroy(this, lifecycleOwner);
        }

        @Override // androidx.lifecycle.DefaultLifecycleObserver, androidx.lifecycle.FullLifecycleObserver
        public /* synthetic */ void onPause(LifecycleOwner lifecycleOwner) {
            DefaultLifecycleObserver.CC.$default$onPause(this, lifecycleOwner);
        }

        @Override // androidx.lifecycle.DefaultLifecycleObserver, androidx.lifecycle.FullLifecycleObserver
        public /* synthetic */ void onStart(LifecycleOwner lifecycleOwner) {
            DefaultLifecycleObserver.CC.$default$onStart(this, lifecycleOwner);
        }

        @Override // androidx.lifecycle.DefaultLifecycleObserver, androidx.lifecycle.FullLifecycleObserver
        public /* synthetic */ void onStop(LifecycleOwner lifecycleOwner) {
            DefaultLifecycleObserver.CC.$default$onStop(this, lifecycleOwner);
        }

        @Override // androidx.lifecycle.DefaultLifecycleObserver, androidx.lifecycle.FullLifecycleObserver
        public void onResume(LifecycleOwner owner) {
            Intrinsics.checkNotNullParameter(owner, "owner");
            DefaultLifecycleObserver.CC.$default$onResume(this, owner);
        }
    });
}
bennyhuo commented 1 year ago

看上去是Java版本影响的。

能帮忙写个复现问题的demo发出来吗?方便我们快速定位问题

CodeIdeal commented 1 year ago

看上去是Java版本影响的。

能帮忙写个复现问题的demo发出来吗?方便我们快速定位问题

demo在这里:https://github.com/CodeIdeal/kace-AbstractMethodError-demo

bennyhuo commented 1 year ago

好的,多谢反馈,我们尽快抽空看下。

RicardoJiang commented 1 year ago

看上去是Java版本影响的。 能帮忙写个复现问题的demo发出来吗?方便我们快速定位问题

demo在这里:https://github.com/CodeIdeal/kace-AbstractMethodError-demo

经过测试,发现是targetSdkVersion为23引起的,SDK 23 的 java 版本是 1.7,升级targetSdkVersion为24就可以解决,成本应该也不高? @CodeIdeal

bennyhuo commented 1 year ago

先关掉了,如果还有问题,可以重新打开继续讨论。感谢支持。

CodeIdeal commented 1 year ago

@RicardoJiang @bennyhuo 感谢你们的工作。

将targetSdkVersion改成24的确就没有问题了。targetSdkVersion 23 -> 24也基本没有大的兼容问题。 今天上班再次测试了一下,发现在高版本(api 30)上把targetSdkVersion改成24的确就没有问题了. 但是在低版本(api 22)上,依旧存在这个问题。

另外有个建议,如果在源码上直接把匿名的DefaultLifecycleObserver的剩下的其他方法都添加空的实现,是不是就不用改targetSdkVersion啦?我感觉这样做能最大程度的增加kace的兼容性。

RicardoJiang commented 1 year ago

@RicardoJiang @bennyhuo 感谢你们的工作。

~将targetSdkVersion改成24的确就没有问题了。targetSdkVersion 23 -> 24也基本没有大的兼容问题。~ 今天上班再次测试了一下,发现在高版本(api 30)上把targetSdkVersion改成24的确就没有问题了. 但是在低版本(api 22)上,依旧存在这个问题。

另外有个建议,如果在源码上直接把匿名的DefaultLifecycleObserver的剩下的其他方法都添加空的实现,是不是就不用改targetSdkVersion啦?我感觉这样做能最大程度的增加kace的兼容性。

最新版本1.7.0-1.0.3-SNAPSHOT已处理,可升级试试

CodeIdeal commented 1 year ago

不好意思,隔这么久才回复。1.7.0-1.0.3-SNAPSHOT的确没有问题了。再次感谢🙏