2012-02-27 45 views
3

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

在此先感谢。

+0

为了您的任务最好使用随时可用的库:http://code.google.com/p/libs-for-android/wiki/ImageLoader – Yahor10 2012-02-27 07:43:37

+0

感谢我已经使用googletv imageloader为我的应用程序:D – 2012-02-27 10:59:40

回答

2

从OO的角度来看,业务逻辑的东西应该始终与UI的东西隔离。我会隔离和集中我的所有业务调用,比如getSong(),getStore()等为POJO,并让我的活动类只专注于UI操作/渲染,这是我要做的事:

  1. 定义接口IBusinessDAO
  2. 定义RealBusinessDAO实现IBusinessDAO
  3. 定义MockBusinessDAO实现IBusinessDAO
  4. 呼叫IBusinessDAO.getSong();里面AsyncTask.doInBackground()因此,在每个不同的活动中您的AsyncTask实现

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

,您AsyncTask.doInBackgroud()将是简洁明快,从而使您的代码更高效,更易于维护。

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

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

希望有所帮助。

+0

可能是我没有解释清楚。我的应用程序以某种方式喜欢Android Market。例如:详细的应用程序活动,它显示应用程序截图,相同类别的应用程序,相同的提供商应用程序,推荐应用程序**所以我创建4个asynctasks来获取数据或将4个函数放在一个asynctask中,并通过调用publishProgress **来更新UI。哪种方式更有效。我已经有了不同的歌曲,应用程序,故事模式......和假数据:D – 2012-02-27 09:16:08

+0

就个人而言,我更喜欢带有publishProgress的单个AsyncTask,只要所有耗时的任务都在后台线程中处理,使用其中一个就足够且更高效,可以使用其中的几个。 – yorkw 2012-02-27 09:33:35

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

可以使用

_initCommonAsyncTask(AsyncTaskName.SEARCH, searchQuery); 

调用的AsyncTask定义枚举您的任务列表这样

public enum AsyncTaskName { 
    SEARCH, REFRESH, LOAD_NEXT; 
}