2016-02-17 125 views
1

我有4个异步任务从互联网加载数据。同时,我用动画展示活动,当任务完成时,我需要启动另一个加载数据的活动。Android:等待多个任务完成

在科特林我的异步方法(同写在Java的异步任务)

private fun getArtistData(name: String) { 
    val getArtistDataAsync = object : AsyncTask<String, Void, Artist>() { 

     override fun doInBackground(vararg args: String?): Artist? { 
      Log.i(TAG, "Получаем данные в AsyncTask для $mArtistName") 
      Caller.getInstance().cache = null 
      return Artist.getInfo(args[0], "26cc2ebf6da38bc646733f661bfc6268"); 
     } 

     override fun onPostExecute(result: Artist?) { 
      super.onPostExecute(result) 
      Log.i(TAG, "Возвращаем данные из AsyncTask для $mArtistName") 
      CommonUtilities.artistInstance = result as Artist; 
     } 
    } 

    val getTopTracksAsync = object : AsyncTask<String,Void,ArrayList<Track>>(){ 
     override fun doInBackground(vararg args: String?): ArrayList<Track>? { 
      Log.i(TAG, "Получаем список песен в AsyncTask для $mArtistName") 
      Caller.getInstance().cache = null 
      return Artist.getTopTracks(args[0], "26cc2ebf6da38bc646733f661bfc6268") as ArrayList<Track>; 
     } 

     override fun onPostExecute(result: ArrayList<Track>?) { 
      super.onPostExecute(result) 
      Log.i(TAG, "Возвращаем список песен из AsyncTask для $mArtistName") 
      CommonUtilities.trackListInstance = result; 
     } 
    } 

    val getSimilarBandsAsync = object : AsyncTask<String,Void,ArrayList<Artist>>(){ 
     override fun doInBackground(vararg args: String?): ArrayList<Artist>? { 
      Log.i(TAG, "Получаем список похожих групп в AsyncTask для $mArtistName") 
      Caller.getInstance().cache = null 
      return Artist.getSimilar(args[0], "26cc2ebf6da38bc646733f661bfc6268") as ArrayList<Artist>? 
     } 

     override fun onPostExecute(result: ArrayList<Artist>?) { 
      super.onPostExecute(result) 
      Log.i(TAG, "Возвращаем список похожих групп из AsyncTask для $mArtistName") 
      CommonUtilities.artistListInstance = result; 
     } 
    } 

    val getTopAlbumsAsync = object : AsyncTask<String,Void, ArrayList<Album>>(){ 
     override fun doInBackground(vararg p0: String?): ArrayList<Album>? { 
      Log.i(TAG, "Получаем список альбомов в AsyncTask для $mArtistName") 
      Caller.getInstance().cache = null 
      return Artist.getTopAlbums(p0[0],"26cc2ebf6da38bc646733f661bfc6268") as ArrayList<Album>?; 
     } 

     override fun onPostExecute(result: ArrayList<Album>?) { 
      super.onPostExecute(result) 
      Log.i(TAG, "Возвращаем список альбомов из AsyncTask для $mArtistName") 
      CommonUtilities.albumListInstance = result; 
     } 
    } 

我想在这里调用我的方法:

val runAllTasks = object : AsyncTask<Void,Void,Void>(){ 
     override fun doInBackground(vararg p0: Void?): Void? { 
      getArtistDataAsync.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, name) 
      getSimilarBandsAsync.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, name) 
      getTopTracksAsync.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, name) 
      getTopAlbumsAsync.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, name) 
      return null 
     } 

     override fun onPostExecute(result: Void?) { 
      super.onPostExecute(result) 

      startActivity(Intent(applicationContext, DetailsActivity::class.java)) 
     } 
    } 

    runAllTasks.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR) 
+0

Kotlin库Kovenant通过使用promise(简单地为'task {...}'),有一个非常简单的模型,然后将它们结合起来,可以创建一个复合承诺,然后可以在部分或全部完成时继续。 http://kovenant.komponents.nl/ ...并且它支持Android开箱即用,只需要一个特殊的小插件,如果你想在UI线程上自动回调。 http://kovenant.komponents.nl/addons/ui/ –

+0

无论Java堆栈溢出的答案如何,都适用于Kotlin。因此,如果你不是在寻找类似Kotlin库的东西来替代异步任务,那么这个问题就是一个骗局。 http://stackoverflow.com/questions/17418194/multiple-callback-waiting-in-android-java和http://stackoverflow.com/questions/25608795/android-how-to-detect-when-multiple-http-请求完成和http://stackoverflow.com/questions/16504352/running-multiple-services-at-one-time-in-android ...和其他 –

+0

更多的标签:http://stackoverflow.com/问题/ tagged/android-asynctask –

回答

1

可以调用它算一个​​常用方法已经完成的asyncTask的编号。事情是这样的:

private static final int NUMBER_ASYNCTASK = 4; 
private static int counter = 0; 

public static synchronized void asyncTaskCompleted() { 
    counter++; 
    if(counter == NUMBER_ASYNCTASK) 
     //start new activity 
} 
+0

它也没有指出哪个线程正在做最后的回调工作,这里来自异步池的随机线程继续到下一个任务,或者可能是UI线程是?不一定是代码中的错误,但需要考虑哪些线程应该继续向前以及哪个线程正在进行调用。 –

+0

也许可以使用CountDownLatch。类似问题的另一个答案是:stackoverflow.com/a/17418772/3679676 –

3

我会用Kovenant库,而不是,它在Android的支持,是微小的,并使得这种类型的东西很容易使用all()combine()and()

Kovenant是Kotlin的承诺库。如果你正在转移到Kotlin,那么这是一个很好的机会来检查让生活更轻松的事情。对于UI线程中的回调,您可以使用UI Module

然后无论在Android还是后端JVM编程中,都可以使用相同的库,相同的语义,并且具有更简单的编程模型。