与Android项目中的源库相比,实现AAR库的结果出乎意料

时间:2019-01-25 06:06:13

标签: java android android-studio aar

摘要

当前行为

与Android Projects中的源库相比,实现AAR库的意外结果。

  • super关键字似乎指向祖父母类而不是直接父类。
  • 即使在父级中声明并覆盖了相同的方法,也将以某种方式覆盖祖父母方法。

这两个问题仅在使用已编译的库AAR时存在,即在使用库源代码实现同一项目时不存在问题。

预期行为

  • 我希望两个对super的调用都能够解析为父类。
  • 我希望重写onCreate会覆盖父类而非祖父母类中的方法。

工作应用

我有一个基于com.example.sourceapp包的Android应用程序

这将使用和管理位于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中包含的super.myBool = true;
  • 我在覆盖的方法中通过onCreate调用了super.onCreate()。 两者都按预期工作。当我将鼠标悬停在super.onCreate上时,Android Studio指示它可以按预期正确解析为父类。

不适用的应用程序

在另一个Android项目com.example.compiledapp.MainActivity中,我依赖于由同一库制成的已编译(调试)的AAR文件,而不是依赖于源库com.example.sourcelibrary

我从com.example.compiledapp.MainActivity顶部的import com.example.sourcelibrary.ParentClass的AAR包中导入所需的类,没有任何解析问题。

稍后在com.example.compiledapp.MainActivity中,我使用与以前相同的代码

super.myBool = true;
super.onCreate()

但是Android Studio指示它无法解析super.myBool = true;中的myBool。

此外,第二行似乎还可以,但是当我将鼠标悬停在第二行时,仔细检查后,Android Studio指出onCreate决心成为祖父母类com.example.someotherlibrary.GrandparentClass的成员,而不是父类com.example.sourcelibrary.ParentClass

当我将鼠标悬停在onCreate覆盖上时,看起来有些对齐,Android Studio指示我是在祖父母类而非父类中覆盖onCreate

为什么/ onCreate如何跳过父方法并覆盖祖父母类?

另外,看起来super关键字正在解析为祖父母类而不是父类。这是我能想到的唯一解释,将导致onCreate解析为GrandparentClass,并且myBool无法解析。我不认为super是这样工作的。

这是正常现象吗,我只是在误解关于继承的一些基本知识?也许在编译为AAR时我做错了什么,使得尽管被声明为public,但父变量/方法仍然无法访问?还是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
    }

}

1 个答案:

答案 0 :(得分:1)

我最终找到了错误。事实证明,在构建包含库模块com.example.sourceapp的{​​{1}}时,构建过程没有更新AAR文件,并且过时的源库代码中显然存在一些错误/过旧(也许是缺少onCreate方法和myBool。不能确定,因为我不记得git历史记录中的哪个位置,因为我只是简单地指出修改的日期是旧的,然后重新构建,而旧的时间戳现在不见了。

无论如何,有用的是转到Android Studio中的com.example.sourcelibrary的gradle菜单,然后导航到源库->任务-> build-> build。尝试直接构建库会引发与SDK版本有关的错误,因此我将其修复并重新生成,然后重新导入到chedulatedapp,它按预期运行。

其他人可能会从中学到的东西是,如果您的AAR依赖项发生了奇怪的事情,请检查您从中构建AAR的源代码实际上是在构建和更新AAR文件,因为Android Studio显然没有构建围绕库的应用程序时引发错误。

也许应用程序级别gradle中的SDK设置会覆盖库级别gradle设置,并允许其无错误地构建应用程序,并且实际上是在仅在APK内构建更新的库?不知道为什么,但是至少从中学到了总的教训。