我試圖實現2個異步任務,其中一個應該等待另一個完成。AsyncTask如何在沒有deadLock的情況下等待另一個
我做一個測試案例吧,看起來像這樣:
public class MainActivity extends Activity{
public static boolean SYNCING = false;
public static Object LOCK = new Object();
public static void setSync(){
Log.i(TAG, "setting Sync=true");
synchronized (LOCK) {
SYNCING = true;
}
}
public static void waitForSync(){
Log.i(TAG, "waiting for Sync");
synchronized (LOCK) {
try{
while (SYNCING){
LOCK.wait();
}
} catch (InterruptedException ignore){}
}
}
public static void setSyncFinish(){
Log.i(TAG, "setSyncFinish to notify all");
synchronized (LOCK) {
SYNCING = false;
LOCK.notifyAll();
}
}
public class WaitingOnLoaderTask extends AsyncTask<Void, Void, Void>{
@Override
protected Void doInBackground(Void... params) {
Log.i(TAG, "doInBackground of WaitingForLoaderTask");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
}
waitForSync();
Log.i(TAG, "finishedWaiting!");
return null;
}
}
public class LoaderTask extends AsyncTask<Void, Void, Void>{
long mRuntime;
int mTimes;
public LoaderTask(long runtime, int times){
mRuntime = runtime;
mTimes = times;
}
@Override
protected Void doInBackground(Void... params) {
while(mTimes >= 0){
Log.i(TAG, "sleeping for " + mTimes + " times for " + mRuntime + " milliseconds");
mTimes--;
try {
Thread.sleep(mRuntime);
} catch (InterruptedException e) {
Log.e("MainActivity", "Interrupted", e);
}
}
setSyncFinish();
return null;
}
}
}
但我不能讓WaitingOnLoaderTask
正確地等待。如果我的onCreate運行此
new WaitingOnLoaderTask().execute((Void[])null);
new LoaderTask(1000, 5).execute((Void[])null);
我得到這樣一個logOutput(死鎖發生):
03-08 18:17:23.309: I/myUniqueLogTag(4432): setting Sync=true
03-08 18:17:23.317: I/myUniqueLogTag(4432): doInBackground of WaitingForLoaderTask
03-08 18:17:23.817: I/myUniqueLogTag(4432): waiting for Sync
和
new LoaderTask(1000, 5).execute((Void[])null);
new WaitingOnLoaderTask().execute((Void[])null);
我得到一個日誌是這樣的:
03-08 18:18:53.082: I/myUniqueLogTag(4621): sleeping for 5 times for 1000 milliseconds
03-08 18:18:54.082: I/myUniqueLogTag(4621): sleeping for 4 times for 1000 milliseconds
03-08 18:18:55.090: I/myUniqueLogTag(4621): sleeping for 3 times for 1000 milliseconds
03-08 18:18:56.082: I/myUniqueLogTag(4621): sleeping for 2 times for 1000 milliseconds
03-08 18:18:57.090: I/myUniqueLogTag(4621): sleeping for 1 times for 1000 milliseconds
03-08 18:18:58.106: I/myUniqueLogTag(4621): sleeping for 0 times for 1000 milliseconds
03-08 18:18:59.113: I/myUniqueLogTag(4621): doInBackground of WaitingForLoaderTask
03-08 18:18:59.113: I/myUniqueLogTag(4621): setSyncFinish to notify all
03-08 18:18:59.621: I/myUniqueLogTag(4621): waiting for Sync
03-08 18:18:59.621: I/myUniqueLogTag(4621): finishedWaiting!
所以我想一個是防止o運行。他們是否實際上在同一個線程中計算了它們的doInBackground
,並且LOCK.wait()
阻止此線程進一步執行?
有沒有辦法解決它(並保持與Android 2.2兼容)?
注意: 第二次基本上是我想要的,但在其他任務實現中,我不能確定WaitingOnLoaderTask
僅在另一個完成時纔會執行。
「我試圖實現2個異步任務,其中一個人應該等待另一個完成」 - 爲什麼它不只是一個'AsyncTask'呢? – CommonsWare 2013-03-08 17:28:39
如果你想保持任務分開,或者從另一個的'onPostExecute()'調用。 – Geobits 2013-03-08 17:29:23
不可能。在「真實世界的使用」中,第一個任務是將事情與服務器同步並將結果存儲在數據庫中。它從'Application'調用。另一個從db接收這些數據,但必須等待,直到第一個完成同步,並且可以在同步完成之前被調用。在'onPostExecute'中開始第二個是沒有意義的,因爲結果將無處可用。 – 2013-03-08 17:33:54