如何在不重叠的情况下对AsyncTasks执行多个相关调用?

时间:2014-04-23 21:57:30

标签: android android-asynctask synchronization data-synchronization

我有一个需要重复调​​用Web API的应用程序。实际上,它会迭代SQL表中的记录,并使用适当的数据向Web服务器发出唯一的调用。这是一种数据同步。

据我了解,当对API执行此类HTTP请求时,它应该在AsyncTask中发生以避免挂起UI,所以我创建了我的AsyncTask类来发出请求并解析响应,但是我需要将此数据传递回调用类。

最重要的是,我不希望调用类并行运行这些请求。我希望它发出一个请求,而不是迭代到表中的下一个记录,并在第一个请求完成之前发出第二个请求。所以在某种程度上,我希望这是阻塞,但仍然在一个单独的线程中,因此UI不会冻结。至少,我认为这就是我想要的。

伪代码就是这样的:

// caller function
public void synchronize(){
    load all records from sql table
    for each record:
        if record type is X:
            new asyncX().execute(record)
            // once this completes successfully, 
            // I want to do something with the return value here, 
            // before going on to the next iteration
            // 
            // and eventually when there is some UI here, 
            // show some nice spinny logo and maybe some text for 
            // what's going on right now
        if record type is Y:
            new asyncY().execute(record)
            // same as above
}

// Async class
public class asyncX extends AsyncTask<RecordType,Void,RecordType> {
    protected RecordType doInBackground(RecordType... record) {
        convert record to json
        make http request
        receive http response
        parse response
        return record
    }
}

我正在考虑这样做的方法是将同步功能更改为一次只运行一条记录,调用异步任务,然后结束,然后异步任务回调到synchronize_followup()函数,该函数执行的操作是什么它需要处理返回值,然后再次开始同步备份,但我不确定我喜欢它。

关于如何进行的想法?

2 个答案:

答案 0 :(得分:1)

您想要处理此问题的方式已经发明了线程同步,因此您无需按照自己的方式实现它。

有一个类似于Semaphore的类CountDownLatch。当您声明一个对象并通过.wait()激活锁定机制时,它将冻结执行更多代码,直到您发出.countDown()语句。实际上,如果您宣布CountDownLatch(1)可能会产生您正在寻找的效果。

CountDownLatch's reference page上有一个关于如何通过阻止一个Thread的执行来实现它的一个很好的例子,取决于其他人的执行。

答案 1 :(得分:0)

为了满足我的需求,我将synchronize功能转换为AsyncTask,从我的UI线程中转出,并将传出的HTTP请求保留为常规功能(因此,它们会阻止)。

这意味着同步过程在后台进行,不会影响UI线程,并且每个传出的API调用都会按顺序进行。