Android:等待多个任务完成

时间:2016-02-17 18:09:28

标签: android android-asynctask kotlin

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

我在Kotlin上的异步方法(与在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)

2 个答案:

答案 0 :(得分:3)

我会使用Kovenant库,它在Android上有支持,很小,使用all()combine()and()可以轻松完成此类操作。

Kovenant是Kotlin的Promise库。如果你要搬到Kotlin,这是一个很好的机会来检查让生活更轻松的事情。对于UI线程上的回调,您可以使用UI Module

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

答案 1 :(得分:1)

您可以调用synchronized常用方法来计算已经完成的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
}