最佳实践:扩展或覆盖Android库项目类

mja*_*ama 32 java architecture eclipse android design-patterns

我们正在使用Android库项目在Android应用程序的不同构建(目标)之间共享核心类和资源.每个特定目标的Android项目都引用了Core库项目(在幕后,Eclipse创建并引用了引用的库项目中的jar).

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

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

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

是否有其他策略来覆盖或扩展Android库项目类?在Android应用目标中共享和扩展常见类的一些最佳做法是什么?

Bor*_*dov 17

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

@yorkw对于最新版本的ADT Plugin for Eclipse http://developer.android.com/sdk/eclipse-adt.html不适用

从版本17更改日志

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

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

在此之前,从库项目更新覆盖活动很容易,只需排除该类.现在库被包含为jar文件,并且无法从jar依赖项中排除类文件.

编辑:

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

我创建了一个简单的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);
}
}
Run Code Online (Sandbox Code Playgroud)

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

重要信息:所有引用覆盖活动的意图都应该通过util类以下列方式创建:

Intent intent = ActivityUtil.createIntent(MainActivity.this, SampleActivity.class);
...
startActivity(intent);
Run Code Online (Sandbox Code Playgroud)

  • 这是一个很好的解决方案.我做了一些更改,以允许Extended类驻留在`Application Project`的包而不是`Library Project`包中.如果您认为这是一项改进,您可以加入编辑.我改变了你的`extClassName`的方式:`String pkgName = context.getPackageName(); 字符串extClassName = pkgName +"." + clazz.getSimpleName()+"Extended";`你还需要将上下文传递给`getActivityClass()` (3认同)