我有一个需要重复调用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()函数,该函数执行的操作是什么它需要处理返回值,然后再次开始同步备份,但我不确定我喜欢它。
关于如何进行的想法?
答案 0 :(得分:1)
您想要处理此问题的方式已经发明了线程同步,因此您无需按照自己的方式实现它。
有一个类似于Semaphore
的类CountDownLatch
。当您声明一个对象并通过.wait()
激活锁定机制时,它将冻结执行更多代码,直到您发出.countDown()
语句。实际上,如果您宣布CountDownLatch(1)
可能会产生您正在寻找的效果。
在CountDownLatch's reference page上有一个关于如何通过阻止一个Thread
的执行来实现它的一个很好的例子,取决于其他人的执行。
答案 1 :(得分:0)
为了满足我的需求,我将synchronize
功能转换为AsyncTask,从我的UI线程中转出,并将传出的HTTP请求保留为常规功能(因此,它们会阻止)。
这意味着同步过程在后台进行,不会影响UI线程,并且每个传出的API调用都会按顺序进行。