如何有效地使用Asynctask

时间:2012-02-27 07:38:31

标签: android thread-safety android-asynctask

我是Android新手。我想问你们关于Asynctask的事。我有一个活动显示项目(应用程序,歌曲,故事..)详细信息。它需要许多相关数据,如截图,相关应用程序(歌曲,故事),......那么Asynctask的最佳实现是什么?我是否为每个任务创建了一个asynctask(例如:2 asynctask:1用于获取屏幕截图,1用于获取相关项目...)或者将所有内容放入doInBackGround并发布进度?

提前致谢。

2 个答案:

答案 0 :(得分:2)

从OO的角度来看,业务逻辑应始终与UI内容隔离开来。我会将所有业务调用(如getSong(),getStore()等)隔离并集中到POJO中,并保持我的活动类只关注UI操作/渲染,这就是我的工作方式:

  1. 定义接口IBusinessDAO
  2. 定义RealBusinessDAO实施IBusinessDAO
  3. 定义MockBusinessDAO实施IBusinessDAO
  4. 致电IBusinessDAO.getSong();在AsyncTask.doInBackground()

    public class MyActivity extends Activity {
      IBusinessDAO businessDAO;
    
      ... ...
    
      private class MyAsyncTask extends AsyncTask<Void, Void, Void> {
        ... ...        
    
        protected void doInBackground(Void... params) {
          businessDAO.getSong();
        }
      }
    
      ... ...
    
      public void onCreate(Bundle savedInstanceState) {
        if (runInTest)
          businessDAO = new MockBusinessDAO();
        else
          businessDAO = new RealBusinessDAO();
    
        new myAsyncTask().execute();
      }
    
    }
    
  5. 因此,在不同活动中的每个AsyncTask实现中,您的AsyncTask.doInBackgroud()将简单而干净,从而使您的代码更加高效和可维护。

    它还有助于提高代码可测试性,对于业务逻辑进行单元测试,因为它是一个POJO,您可以纯粹使用JUnit编写测试用例。有时候我们想测试UI组件而我们并不关心底层业务逻辑是如何实现的,例如,我的业务逻辑连接到远程http服务器下载一些json数据,我不想每次都这样做我只是想要测试UI布局,对于这种情况,我可以轻松地更改我的所有活动使用MockBusinessDAO(一种Spring的DI概念),测试UI组件而不关心实际业务逻辑的实现方式。

    最后,它还提高了代码的可重用性,因为你的businesDAO与Andriod无关,而不是经典的POJO,此外,你不需要关注BusinessDAO实现中的任何并发性,因为它的所有方法都将在AsyncTask中调用.doInBackground()方法。

    希望有所帮助。

答案 1 :(得分:1)

我在一个AsyncTask中实现了这类任务

private void _initCommonAsyncTask(AsyncTaskName currentTaskName,
        String searchQuery) {
    CommonAsyncTask task = new CommonAsyncTask(currentTaskName, searchQuery);
    task.execute();
    taskReference = new WeakReference<CommonAsyncTask>(task);
}

/**
 * Asynchronous Task for different functionalities.
 * 
 */
private class CommonAsyncTask extends AsyncTask<Void, Void, Void> {
    private final String searchQuery;
    private AsyncTaskName currentTaskName;

    /**
     * Default constructor
     */
    public CommonAsyncTask(AsyncTaskName currentTaskName, String searchQuery) {
        super();
        this.searchQuery = searchQuery;
        this.currentTaskName = currentTaskName;
    }

    @Override
    protected void onPostExecute(Void result) {
        switch (currentTaskName) {
        case SEARCH:
            // Reinitialized the list view
            break; 
        case REFRESH:
            // Reinitialized the list view
            break;
        case LOAD_NEXT:
            // Reinitialized the list view
            break;
        default:
            break;
        }
        super.onPostExecute(result);
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }

    @Override
    protected Void doInBackground(Void... params) {
        switch (currentTaskName) {
        case SEARCH:
            // My searching stuff here
            break;
        case REFRESH:
            // my refreshing stuff here
            break;  
        case LOAD_NEXT:
            //my load next 50 orders here
            break;  
        default:
            break;
        }
        return null;
    }
}

您可以使用

调用Asynctask
_initCommonAsyncTask(AsyncTaskName.SEARCH, searchQuery);

在枚举中定义您的任务列表

public enum AsyncTaskName {
    SEARCH, REFRESH, LOAD_NEXT;
}