Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java's lack of template inheritance is causing major code duplication headaches in Android. Any solutions?

This is Android specific.

I derive all of my Activities in Android from a custom class that provides a nice, clean place to put common code used by all layouts in the application, especially some common setContentView() override code that injects layouts into my layouts. So here is what a typical hierarchy looks like:

MyActivity extends MyBaseClass -> MyBaseClass extends Activity -> Activity

For one of my apps, I needed Google Maps support. So I tried to turn MyBaseClass into a template/generic so that I could do something like:

MyActivity extends MyBaseClass<MapActivity> -> MyBaseClass<T> extends T -> T

Which, of course, failed to compile because Java templates/generics are not nearly as useful as C++ templates as I discovered shortly after the attempt. So I ended up creating a whole separate class as a temporary workaround:

MyActivity extends MyBaseMapClass -> MyBaseMapClass extends MapActivity -> MapActivity

And copied all the code from MyBaseClass into MyBaseMapClass. The code is identical except for a few minor changes involving imports. It works, but it is hardly a good solution.

I crossed my fingers that the above would be the end of the problem and I would never have to revisit it again.

Unfortunately, I'm starting to experiment with a fragment and activity mix with a much more complex base class and the problem of code duplication with the above is getting to be a serious issue. Any time I make a change in one file, I have to remember to clone it to the other files and development is moving fast enough that I'm quickly getting out of sync.

Activity, MapActivity, FragmentActivity, ListActivity, PreferenceActivity, etc. Do I need to make a separate derived class for each and every one of those that I wish to use? I hope not and, for this reason, I've already limited my derivations to begin with (some of my activities don't have certain features as a result). The problem is further exasperated by the fact I sometimes use two separate base classes (where some activities need to inflate even more views into the layout but not all activities need to do so):

MyActivity extends MyBaseClass -> MyBaseClass extends Activity -> Activity

MyActivity2 extends AnotherBaseClass -> AnotherBaseClass extends MyBaseClass -> MyBaseClass extends Activity -> Activity

If I want to use the code for AnotherBaseClass in Maps, I not only have to create MyBaseMapClass, but also AnotherBaseMapClass and copy the code. I'm up to four classes at this point where two of the classes are a couple thousand lines of cloned code. Replicated code bothers me because it makes maintenance and development that much harder to do.

Deriving Android classes introduces complexities such as findViewById() being a part of the Activity base class. That's important because I'm not sure how I would write an interface or composite without running into the same problems I just described.

Anyone here encountered this issue and come up with a workable solution?

like image 204
Paula Bean Avatar asked Oct 31 '12 21:10

Paula Bean


1 Answers

Why don't you just create a helper class with a static function like styleActivity(Activity a)? This seems to be the easier solution in that case than to use inheritance.

like image 140
SimonSays Avatar answered Nov 10 '22 02:11

SimonSays