java - 与 Android 项目中的源库相比,实现 AAR 库的意外结果
问题描述
概括
当前行为
与 Android 项目中的源库相比,实现 AAR 库的意外结果。
super
关键字似乎指向祖父类而不是直接父类。- 即使在父级中声明并覆盖了相同的方法,也以某种方式覆盖了祖父级方法。
这两个问题仅在使用库的编译 AAR 时存在,即使用库源代码实现相同项目时不存在问题。
预期行为
- 我希望这两个调用都能
super
解析为父类。 - 我希望覆盖
onCreate
覆盖父类而不是祖父类中的方法。
工作应用程序
我有一个基于包的 Android 应用程序com.example.sourceapp
这使用和管理位于 中的单独库的源代码,com.example.sourcelibrary
我们将在其中调用一个类ParentClass
。
在ParentClass
我有两个感兴趣的成员。
- 一个名为的公共布尔值
myBool
,起源于ParentClass
- 覆盖该
android.app.Activity.onCreate
方法的方法,该方法也被GrandparentClass
其他库中的某个祖父类覆盖和继承com.example.someotherlibrary
。
在我的com.example.sourceapp.MainActivity
我做两件事。
- 我扩展
com.example.sourcelibrary.ParentClass
和修改myBool
包含在ParentClass
using 中super.myBool = true;
。 - 我在被覆盖的方法中调用
onCreate
via 。super.onCreate()
两者都按预期工作。当我将鼠标悬停在super.onCreate
Android Studio 上时,表明它可以按预期正确解析为父类。
不工作的应用程序
在不同的 Android 项目中,我依赖于由同一个库生成的已编译(调试)AAR 文件,com.example.compiledapp.MainActivity
而不是依赖于源库。com.example.sourcelibrary
我从顶部的 AAR 包中导入所需的类,com.example.compiledapp.MainActivity
没有import com.example.sourcelibrary.ParentClass
任何解决问题。
稍后com.example.compiledapp.MainActivity
我使用与以前相同的代码
super.myBool = true;
super.onCreate()
但 Android Studio 表示它无法解析 myBool 中的super.myBool = true;
.
此外,第二行似乎解决得很好,但是当我将鼠标悬停在它上面时仔细检查,Android Studio 表明它onCreate
解析为是祖父类的成员com.example.someotherlibrary.GrandparentClass
而不是父类com.example.sourcelibrary.ParentClass
。
查看几行,当我将鼠标悬停在onCreate
覆盖上时,Android Studio 表明我正在覆盖onCreate
祖父类,而不是父类。
为什么/如何onCreate
跳过父方法并覆盖祖父类?
此外,看起来super
关键字正在解析为祖父类而不是父类。这是我能想到的唯一解释,它会导致onCreate
解析为 GrandparentClass 而myBool
无法解析。我不认为这是如何super
工作的。
这是正常的吗?我只是误解了继承的基本原理吗?也许我在编译到 AAR 时做错了,以至于尽管被声明为公共的父变量/方法变得不可访问?或者,Android Studio 可能会根据我不知道的一些规则优先选择一个包而不是另一个包?
工作代码
package com.example.sourceapp;
import android.os.Bundle;
import com.example.sourcelibrary.ParentClass;
public class MainActivity extends ParentClass {
// Shows to Override onCreate in ParentClass
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); // super resolves to ParentClass
super.myBool = true; // super resolves to ParentClass
}
}
不工作的代码
package com.example.compiledapp;
import android.os.Bundle;
import com.example.sourcelibrary.ParentClass;
public class MainActivity extends ParentClass {
// Shows to Override onCreate in GrandparentClass
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); // super resolves to Grandparent
super.myBool = true; // does not resolve
}
}
解决方案
我最终找到了错误。事实证明,在构建com.example.sourceapp
包含库模块com.example.sourcelibrary
的 my 时,构建过程没有更新 AAR 文件,并且在过时的源库代码中显然存在错误/旧问题(可能缺少 onCreate 方法和 myBool。不确定因为我不记得在我的 git 历史中它会在哪里,因为我只是简要地指出修改日期是旧的,然后重建并且旧的时间戳现在已经消失了。
不管怎样,进入 Android Studio 的 gradle 菜单com.example.sourceapp
并导航到 sourcelibrary-->Tasks-->build-->build 有帮助。尝试直接构建库会引发与 SDK 版本相关的错误,因此我修复了此问题并重新构建,重新导入到已编译的应用程序中,它按预期工作。
其他人可能从中学到的一点是,如果您的 AAR 依赖项发生了一些奇怪的事情,请检查您构建 AAR 的源代码是否实际上正在构建和更新 AAR 文件,因为 Android Studio 显然不会引发错误在构建围绕图书馆的应用程序时。
也许应用程序级别gradle中的SDK设置覆盖了库级别gradle设置并允许它构建应用程序而没有错误,并且更新的库实际上是构建的,但仅在APK内?不确定,确切的原因,但至少吸取了一个整体的教训。
推荐阅读
- sql - TIBCO MDM 目录冲突
- bundle - Symfony 5 可重用捆绑配置 TreeBuilder:路径的无效类型
- python-3.x - pip 不构建 .so 文件
- python-3.x - 获取txt文件中的特定行
- json - xml到json转换中的空元素
- spring-boot - 如何使用 gradle 项目工具在 IntelliJ Ultimate 中调试远程 Spring Boot 应用程序
- api - 如何使用 Test Rail API 从运行中获得超过 250 个的列表测试
- html - 悬停时在卡片中显示内容
- configuration - 运行 Go 程序的实现启动,输出 exec: not started
- assembly - 如果硬件不支持trap指令,但支持中断和异常,是否可以跳转到内核模式