You can create classes that contain most of your boilerplate code. E.g.
public class SpecialAsyncTask<T> extends AsyncTask<String, Void, T> {
public interface ResultProvider<T> {
T generateResultInBackground(String... params);
}
public interface ResultConsumer<T> {
void handleResultInForeground(T result);
}
private final ResultProvider<T> mProvider;
private final ResultConsumer<T> mConsumer;
private SpecialAsyncTask(ResultProvider<T> provider, ResultConsumer<T> consumer) {
mProvider = provider;
mConsumer = consumer;
}
@Override
protected T doInBackground(String... params) {
return mProvider.generateResultInBackground(params);
}
@Override
protected void onPostExecute(T result) {
mConsumer.handleResultInForeground(result);
}
public static <T> void execute(ResultProvider<T> provider, ResultConsumer<T> consumer, String... params) {
new SpecialAsyncTask<T>(provider, consumer).execute(params);
}
}
is an example how you could keep Object1
as a generic parameter while being able to specify an object that only needs to implement an interface to handle code that would otherwise have to be inside a new AsyncTask
instance.
With a schema like that you could for example define some common code as static content:
class Providers {
public static final ResultProvider<String> HTTP_GETTER = new ResultProvider<String>() {
@Override
public String generateResultInBackground(String... params) {
return MagicHttpLibrary.getContentAsString(params[0]);
}
};
}
And you can just use Providers.HTTP_GETTER
as parameter instead of implementing doInBackground
. Or create a new class hierarchy of that implement one of those interfaces with different methods to access them (like factories for example)
Use of above example would look for example like below
class User extends Activity implements ResultConsumer<String> {
@Override
protected void onCreate(Bundle savedInstanceState) {
SpecialAsyncTask.execute(Providers.HTTP_GETTER, this , "http://google.com");
SpecialAsyncTask.execute(Providers.HTTP_GETTER, this , "http://yahoo.com");
}
@Override
public void handleResultInForeground(String result) {
Toast.makeText(this, result, Toast.LENGTH_LONG).show();
}
}
and there is more or less no repeated code besides the different method calls. It depends on how you want to use a class and what actually changes in the code to know how to design something like that. Identify the parts that need to be parametrized and move code that repeats into a re-used place (inheritance / composition).