最佳做法:扩展或覆盖 Android 库项目类

我们正在使用 Android 库项目在 Android 应用程序的不同版本(目标)之间共享核心类和资源。每个特定目标的 Android 项目都引用核心库项目(在后台,Eclipse 从引用的库项目创建并引用 jar)。

覆盖图像和 XML 布局等资源很容易。生成应用时,放置在目标项目中的资源文件(如应用图标或 XML 布局)会自动覆盖具有相同名称的核心库的资源。但是,有时需要重写类以启用特定于目标的行为。例如,亚马逊目标偏好设置屏幕不能包含指向 Google Play 应用页面的链接,这需要更改亚马逊项目的偏好设置.xml和偏好设置活动类。

目标是减少目标项目之间的重复代码量,同时从 Core 库中删除尽可能多的特定于目标的代码。我们提出了几种实现特定于不同目标的逻辑的方法:

  1. 在核心库类中编写特定于目标的函数,并使用 if/switch 块根据产品 SKU 选择行为。这种方法不是很模块化,并且会使核心库代码库膨胀。
  2. 扩展目标项目中的特定 Core 类,并根据需要重写基(Core)类函数。然后在 Core 库中保留对基类对象的引用,并使用扩展类对象实例化它(从如何重写 Android 库项目中的类?)

是否有其他策略可以覆盖或扩展 Android 库项目类?在 Android 应用目标之间共享和扩展常见类的最佳做法有哪些?


答案 1

库项目被引用为原始项目依赖项(基于源代码的机制),而不是编译的 jar 依赖项(基于编译代码的库机制)。

@yorkw对于最新版本的 Eclipse ADT 插件来说,情况并非如此 http://developer.android.com/sdk/eclipse-adt.html

来自版本 17 更新日志

新的构建功能 添加了自动设置 JAR 依赖项的功能。/libs 文件夹中的任何.jar文件都将添加到构建配置中(类似于 Ant 构建系统的工作方式)。此外,库项目所需的.jar文件也会自动添加到依赖于这些库项目的项目中。(更多信息)

更多信息 http://tools.android.com/recent/dealingwithdependenciesinandroidprojects

在此之前,更新覆盖“来自库的活动”项目很容易,只需排除该类即可。现在,库作为 jar 文件包含在内,并且无法从 jar 依赖项中排除类文件。

编辑:

我从库jar中覆盖/扩展活动的解决方案:

我创建了一个简单的 util 类:

public class ActivityUtil {

private static Class getActivityClass(Class clazz) {

    // Check for extended activity
    String extClassName = clazz.getName() + "Extended";
    try {
        Class extClass = Class.forName(extClassName);
        return extClass;
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
        // Extended class is not found return base
        return clazz;
    }
}

public static Intent createIntent(Context context, Class clazz) {
    Class activityClass = getActivityClass(clazz);
    return new Intent(context, activityClass);
}
}

为了覆盖库的“SampleActivity”类,它是依赖于该库的项目,请在同一包中的项目中创建一个名为SampleActivityExtended的新类,并将新活动添加到AndroidManifest.xml。

重要说明:引用被覆盖活动的所有意向都应通过以下方式通过 util 类创建:

Intent intent = ActivityUtil.createIntent(MainActivity.this, SampleActivity.class);
...
startActivity(intent);

答案 2

在幕后,Eclipse 从引用的库项目创建并引用一个 jar。

这不太准确。库项目被引用为原始项目依赖项(基于源代码的机制),而不是编译的 jar 依赖项(基于编译代码的库机制)。目前,Android SDK 不支持将库项目导出到自包含的 JAR 文件。库项目必须始终间接编译/生成,方法是在依赖应用程序中引用库并生成该应用程序。当构建依赖项目时,需要从库项目中过滤/合并的已编译源代码和原始资源将被复制并正确包含在最终的apk文件中。请注意,Android 团队从 r14 开始改进整个库项目设计(将其从基于 ource 的机制转移到基于编译代码的库机制),如之前的博客文章中所述。

在 Android 应用目标之间共享和扩展常见类的最佳做法有哪些?

Android给出的解决方案是Library Project
Java给出的解决方案是继承多态性
总而言之,最佳实践IMO是您在问题中提到的第二个选项:

2.扩展目标项目中的特定Core类,并根据需要覆盖基(Core)类函数。然后在核心库中保留对基类对象的引用,并使用扩展类对象实例化它(来自Android库项目 - 如何覆盖类?

根据我个人的经验,我总是使用Android库项目(有时使用常规Java项目,用于实现/构建仅包含POJO的common-lib.jar)管理公共代码,例如SuperActivity或SuperService,并在多态性的依赖项目中扩展/实现适当的类/接口。


推荐