2011-03-28 11 views
0

내 응용 프로그램에는 웹 사이트에서 물건을 다운로드하는 백그라운드 작업 (AsyncTask 사용)이 있습니다.두 가지 활동에서 동일한 배경 작업 실행

이 작업은 두 개의 별도 활동에서 호출 할 수 있으며 두 번 호출 할 수 있습니다. 따라서 "activity1"에서 백그라운드 작업 인 "update"가 호출되고 잠시 동안 실행됩니다 (일반적으로 5-10 초 정도 걸립니다). 그런 다음 실행 중 사용자는 "activity2"로 전환하고 "update"를 다시 실행합니다. 이렇게하면 문제가 발생합니다. 둘 다 동시에 데이터베이스를 지우려고 할 때 (명령 : DELETE FROM table) 동시에 "데이터베이스 잠김"오류가 발생하면 충돌이 발생합니다. 또는 데이터베이스에 같은 항목을 넣어 중복을 시도합니다.

저는 작업이 활성화되어있을 때 정적 부울 플래그를 true로 설정하여이 문제를 해결하려고했습니다. 작업이 호출되면이 플래그를 검사하고 참인 경우 (즉, 다른 스레드에서 실행중인 동일한 작업)이 플래그가 지워질 때까지 처리기를 사용하여 대기 루프로 이동 한 다음 반환됩니다. 이렇게하면 백그라운드 작업이 반환 될 때 업데이트가 완료되었는지 확인할 수 있습니다. 나는 루퍼를 사용해야한다 : 이것은 때때로 "쓰레드 당 하나의 루퍼 만 만들 수있다"라는 오류와 함께 실패한다.

if (active) { 
     Looper.prepare(); 
     handler = new Handler(); 
     handler.postDelayed(new Runnable() { 
      int count = 0; 

      @Override 
      public void run() { 
       if (active) { 
        count++; 
        if (count < 1000) 
         handler.postDelayed(this, 100); 
       } 
      } 
     }, 100); 
     Looper.loop(); 
     active = false; 
     return "done"; 
    } 

그리고 종종에 걸 것으로 보인다 설상가상 : 그리고 난 정말 단 하나의 루퍼를 시작할 수있는 방법으로 그것을 가지고,이 배경 작업의 시작에 나타나는 잘못된 코드입니다 돌아 오지 않고이 루프.

그런 상황을 해결하는 방법에 대한 아이디어가 있으십니까?

답변

0

데이터베이스 잠금 문제를 ContentProvider로 래핑하여 해결했습니다. 이전 인스턴스가 완료되기 전에 다시 호출되는 메소드에 대한 문제점 외에도 데이터베이스에 쓰려고 할 때 다른 백그라운드 스레드에서 실행되는 다른 메소드가 충돌하는 문제점이있었습니다.

공식적으로 응용 프로그램간에 데이터를 공유하도록 설계되었으며, 단일 응용 프로그램의 스레드간에 데이터를 공유하는 데 적합합니다. ContentProvider는 잠금 문제가 발생하지 않도록합니다.

0

대신 동기화를 사용하지 않는 이유는 무엇입니까? 그것은 동시성 문제처럼 들립니다. 첫 번째 백그라운드 작업이 실행중인 경우 두 번째 백그라운드 작업이 첫 번째 백그라운드 작업이 완료 될 때까지 잠자기 상태인지 확인해야합니다.

사용자가 활동 번호 2로 전환하면 활동 번호 1의 백그라운드 작업이 취소됩니다.

+0

이제 답변을 드리겠습니다. 나는 동기화에 관해서는 모릅니다 ... 당신은 이것에 대해 더 자세한 정보를 줄 수 있습니까? – Wouter

+0

다음은 처음부터 시작하는 내용입니다. http://download.oracle.com/javase/tutorial/essential/concurrency/sync.html – Vino

0

AsyncTask 대신 IntentService을 사용할 수 있습니다. Android Service concept을 살펴보십시오. IntentService 클래스는 한 번에 하나의 요청 만 처리하도록합니다.

this 대답은 활동 콜백 통신으로 IntentService를 구현하는 동안 매우 유용합니다.

+0

흥미로운 개념이지만 여러 스레드의 데이터베이스 액세스입니다. 동시에. 지금 ContentProvider를 사용하려고하는 것이 더 적절합니다. 앱 간 공유를위한 것이지만 동일한 앱의 두 개 이상의 스레드를 공유 할 때도 좋습니다. – Wouter

관련 문제