2013-06-27 1 views
1

서버 요청을 한 다음 요청이 완료되면 작업을 수행해야하는 Android 앱을 사용 중입니다. 여기콜백을 보장하는 가장 좋은 방법은 항상 비동기 적으로 실행됩니까?

makeRequest(new SomeTask{ 
    onDone() { 
     // Do actionB with queue 
    } 
}); 

// Do actionA with queue. Must be execute first!! 

의사 코드에 makeRequest의 구현 것 : 여기에 상황을 설명하는 데 도움이되는 몇 가지 의사 코드는 예상대로 보통 actionAactionB 전에 발생

makeRequest(SomeTask task) { 
    if(canDoOptimization) { // if true, don't need to make request 

     // It's a bad idea to execute this immediately. 
     // Wish I could wait until the current thread of execution was done... 
     task.onDone(); 
     return; 
    } 

    asyncTask = new AsyncTask<SomeTask, Void, Void>() { 
     doInBackground(SomeTask... task) { 
      // Make server request... 

      task.onDone(); 
     } 
    } 
    asyncTask.execute(task); 
} 

,하지만 경우에 우리는 네트워크를 피할 수있는 곳 요청시 SomeTask.execute이 즉시 호출됩니다. 이로 인해 actionB앞에 나타나고actionA이 나옵니다. 이 일이 발생하지 않는다고 보장 할 수있는 방법이 있습니까?

저는이 상황을 여러 번 자바 스크립트에서 실행했습니다. 이러한 경우 SomeTask.execute 전화를 setTimeout 또는 setImmediate으로 포장하여 올바른 비동기 의미를 유지합니다. 명확성을 위해

, 여기에 자바 스크립트에서 동일한 버그의 예 : 나는 자바/안드로이드에서 무엇을해야 https://gist.github.com/xavi-/5882483

어떤 생각?

+0

왜하여 makeRequest 전에 액션 A를 호출 할 수 없습니다 : 이것은 AsyncTsak이 스레드 풀에서 실행되도록 지정하여 고정? –

+0

그럴 수도 있지만 상당한 리팩토링이 필요합니다. 또한 일반적인 해결책이 있기를 바랬으므로 어쨌든이 문제를 염두에 두지 않아야합니다. – Xavi

+0

시간 제한을 설정하는 것은 매우 해킹 된 솔루션처럼 보입니다. –

답변

1

동기화 세계에 오신 것을 환영합니다. 뮤텍스 또는 잠금 개체는 종종 이러한 목적으로 사용됩니다. Is there a Mutex in Java?

B 작업은 완료시 작업 A가 신호를 보낼 뮤텍스를 기다려야합니다. 그러면 작업이 완료되기 전에 적절한 실행 순서가 보장됩니다.

1

task.onDone()을 요청할 필요가 없더라도 항상 AsyncTask에 넣으십시오.

makeRequest(SomeTask task) { 

    asyncTask = new AsyncTask<SomeTask, Void, Void>() { 
     void doInBackground(SomeTask... task) { 

      if(canDoOptimization) { // if true, don't need to make request 

       // It's a bad idea to execute this immediately. 
       // Wish I could wait until the current thread of was done... 
       task.onDone(); 
       return; 
      } else { 
       // Make server request... 

       task.onDone(); 
      } 
     } 
    } 
    asyncTask.execute(task); 
} 
+0

많은 의미가 있습니다. 불행히도 저는 예를 단순화했습니다. 'canDoOptimization' 체크와 실제 네트워크 호출은 다른 장소에서 발생합니다. 'SomeTask' 객체는 꽤 많이 전달됩니다. 아마도'dummy.AsyncTask'에서'task.onDone()'호출을 래핑 할 수 있을까요? – Xavi

+0

더미 AsyncTask는 가치가있다. 나는 실제로 안드로이드 전문가가 아니야, 나는 어둠 속에서 총을 맞고 있었다 :) – jimbojw

0

왜 순서를 바꿀 수 없습니까? actionA 비동기뿐만 아니라 별도의 AsyncTask를 수행하는 경우

// Do actionA with queue. Must be execute first!! 

makeRequest(new SomeTask{ 
onDone() { 
    // Do actionB with queue 
}); 

, 당신은 actionA의 AsyncTasks의 onPostExecute() 메소드에하여 makeRequest (...)를 호출 할 수 있습니다.

Android Honeycomb 버전부터 AsyncTasks가 동일한 스레드에서 실행되므로 여러 작업이 있으면 서로를 차단할 수 있습니다.

if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.HONEYCOMB) { 
asyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); 
} 
else { 
    asyncTask.execute(); 
} 
관련 문제