Java DRY:一个异步任务的案例

Java DRY:一个异步任务的案例,java,android,android-asynctask,dry,Java,Android,Android Asynctask,Dry,我正在开发一个Android应用程序,它对web服务有很多不同的请求。 每个请求都在AsyncTask的子类中以以下方式完成: (new AsyncTask<String, Void, Object1>() { @Override protected Object1 doInBackground(String... params) { // network request and parsing to Object1 Object1 o

我正在开发一个Android应用程序,它对web服务有很多不同的请求。 每个请求都在
AsyncTask
的子类中以以下方式完成:

(new AsyncTask<String, Void, Object1>() {
    @Override
    protected Object1 doInBackground(String... params) {
        // network request and parsing to Object1
        Object1 obj = new Object1();
        obj1 = Parser.parseObject1(httpClient.execute(...));
        return obj1;
    }

    @Override
    protected Object1 onPostExecute(Object1... ret) {
        return ret[0];
    }
}).execute();
(新的异步任务(){
@凌驾
受保护的Object1 doInBackground(字符串…参数){
//对Object1的网络请求和解析
Object1 obj=新的Object1();
obj1=Parser.parseObject1(httpClient.execute(…);
返回obj1;
}
@凌驾
受保护的Object1 onPostExecute(Object1…ret){
返回ret[0];
}
}).execute();
Object1
是不同对象(
Car
Bicycle
Truck
…)的占位符,每个对象位于不同的
异步任务中

除了在
字符串中返回httpClient的输出并在主线程(UI线程)中进行解析之外,我还有什么选择?避免在UI线程中进行解析如果要解析大量数据,听起来很合理,对吗

-=更新=-

让我重新表述一下这个问题:我要求一种更智能的方法来开发我的应用程序,避免重复(
AsyncTask
有很多样板代码)。我的做法是创建了20多个子类的
AsyncTask
,这显然不是干巴巴的(不要重复)


在iOS中,我们有lambda表达式,因此在web请求中执行回调非常简单和简洁。

谷歌的HTTP请求库在同一个工作线程中执行请求和解析。因此,这是一个很好的编码示例。

您可以创建包含大部分样板代码的类。例如

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);
    }
}
您可以使用
Providers.HTTP_GETTER
作为参数,而不是实现
doInBackground
。或者创建一个新的类层次结构,用不同的方法实现其中一个接口来访问它们(例如工厂)

使用上面的例子看起来像下面的例子

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();
    }
}
类用户扩展活动实现ResultConsumer{
@凌驾
创建时受保护的void(Bundle savedInstanceState){
SpecialAsyncTask.execute(Providers.HTTP_GETTER,此文件)http://google.com");
SpecialAsyncTask.execute(Providers.HTTP_GETTER,此文件)http://yahoo.com");
}
@凌驾
public void handleresultinfound(字符串结果){
Toast.makeText(this,result,Toast.LENGTH_LONG).show();
}
}

除了不同的方法调用之外,几乎没有重复的代码。这取决于您希望如何使用类以及代码中实际发生的更改,以了解如何设计类似的东西。确定需要参数化的部分,并将重复的代码移动到重复使用的位置(继承/组合)。

我不确定您的问题是什么——但在最后一点上,如果可能的话,您应该避免在UI线程上进行解析,特别是如果你要为HTTP调用旋转一个线程,那么在这个线程上进行解析是有意义的,你不必每次都写完整的代码。AsyncTask是一个可以扩展或以其他方式使用的类。@Josepharl我想知道一种更简单的方法,避免AsyncTask需要的重复代码。我为每个AsyncTask子类类型创建了一个类,但在我的项目中,我有20多个AsyncTask类。“这正常吗?”扎普我重新措辞了我的问题。请再看一看。我很欣赏如果你的用例是HTTP调用,我建议你使用一个库来完成复杂的类/API设计,以减少重复。您可以围绕asynctask编写自己的包装(例如,
CursorLoader
基于
asynctask
,使用方式完全不同),但这需要大量工作。您可以尝试创建一个抽象类,只使用
Object1
作为泛型参数,这样就可以获得较少的样板文件。或者传入一个策略模式,比如object,它以一种通用的方式处理这些事情。很抱歉,我认为没有必要使用Google的截击。我只是在问一种优化的、干巴巴的方法,用不同的回调创建不同的web请求,而不创建大量的
AsyncTask
s子类
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();
    }
}