Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best practice: Extending or overriding an Android library project class

We're using an Android Library Project to share core classes and resources across different builds (targets) of our Android application. The Android projects for each specific target reference the Core library project (behind the scenes, Eclipse creates and references a jar from the referenced library project).

Overriding resources such as images and XML layouts is easy. Resource files placed in the target project, such as the app icon or an XML layout, automatically override the core library's resources with the same name when the app is built. However, sometimes a class needs to be overridden to enable target-specific behavior. For example, the Amazon target preferences screen cannot contain a link to the Google Play app page, requiring a change in the Amazon project's preferences.xml and preferences Activity class.

The goal is to reduce the amount of duplicate code among target projects while removing as much target-specific code from the Core library as possible. We've come up with a couple of approaches to implement logic specific to different targets:

  1. Write the target-specific functions within Core library classes and use if/switch blocks to select behavior based on product SKU. This approach is not very modular and bloats the Core library codebase.
  2. Extend the particular Core class in a target project and override the base (Core) class functions as needed. Then keep a reference to the base-class object in the Core library and instantiate it with an extended class object (from How to override a class within an Android library project?)

Are there other strategies to override or extend an Android library project class? What are some of the best practices for sharing and extending common classes among Android app targets?

like image 402
mjama Avatar asked Mar 30 '12 23:03

mjama


1 Answers

Library project is referenced as a raw project dependency (source-based mechanism), not as a compiled jar dependency (compiled-code based library mechanism).

@yorkw this is not true for the latest versions of ADT Plugin for Eclipse http://developer.android.com/sdk/eclipse-adt.html

From version 17 Change log

New build features Added feature to automatically setup JAR dependencies. Any .jar files in the /libs folder are added to the build configuration (similar to how the Ant build system works). Also, .jar files needed by library projects are also automatically added to projects that depend on those library projects. (more info)

More info http://tools.android.com/recent/dealingwithdependenciesinandroidprojects

Before that, update overwriting of the Activity from Library project was easy, just exclude the class. Now the library is included as jar file, and there is no way to exclude class file from jar dependency.

EDIT:

My solution to overwrete/extend Activity from library jar:

I created a simple util class:

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); } } 

In order to overwrite a library's "SampleActivity" class it a the project which depends on that library, create a new class with the name SampleActivityExtended in the project in the same package and add the new activity to your AndroidManifest.xml.

IMPORTANT: all intents referencing overwritten activities should be created through the util class in the following manner:

Intent intent = ActivityUtil.createIntent(MainActivity.this, SampleActivity.class); ... startActivity(intent); 
like image 102
Borislav Gizdov Avatar answered Sep 28 '22 07:09

Borislav Gizdov