다른 쪽이 완료 될 때까지 기다려야하는 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!
내가 추측하는 것은 실행할 것이다 theres. 그들은 실제로 동일한 스레드에서 doInBackground
을 계산 했습니까? LOCK.wait()
은이 스레드가 더 이상 실행되지 않도록 차단합니까?
해결 방법이 있습니까 (Android 2.2와 호환 가능)?
참고 : 두 번째 시간은 기본적으로 원하는 것입니다. 그러나 다른 작업 구현에서는 다른 하나가 완료되었을 때만 WaitingOnLoaderTask
이 실행되도록 설정할 수 없습니다.
"다른 비동기 작업을 기다려야하는 2 개의 비동기 작업을 구현하려고합니다."- 왜 단지 하나의 AsyncTask가 아닌가? – CommonsWare
다른 하나의'onPostExecute()'에서 호출 된 것이거나, 작업을 별도로 유지하고자한다면. – Geobits
불가능합니다. "realworld usage"에서 첫 번째 작업은 서버와 사물을 동기화하고 결과를 DB에 저장하는 것입니다. 'Application'에서 호출됩니다. 다른 하나는 db로부터이 데이터를 수신하지만, 동기화가 완료되기 전에 첫 번째 동기화가 완료 될 때까지 기다려야하고 호출 될 수 있습니다. 'onPostExecute'에서 두 번째를 시작하는 것은 아무런 의미가 없습니다. –