2014-01-29 4 views
1

IntentService를 확장하는 클래스가 있는데 클래스 A를 말한 다음 클래스 B와 클래스 C로 두 개의 클래스를 추가했습니다.이 클래스는 클래스 A를 확장합니다. 그 이유는 모든 것을 초기화하려고하기 때문입니다. 내가하고 싶은 것은 단순히 클래스 A의 하나 생성자 또는 onHandleIntent에서 일부 동시성 검사를 할 것입니다IntentService 동시성

@Override 
protected void onHandleIntent(Intent intent) { 
    super.onHandleIntent(intent); 
      //Specific init stuff 
} 

:처럼 그 코드가 클래스 B와 C 그래서 클래스 B와 C의 onHandleIntent 방법에서 재사용 될 수 있도록 클래스 A 보인다. 예를 들어, 메소드 x가 사용되고있을 때 (어떤 클래스가 그것을 사용하는지는 중요하지 않다.) 나는이 메소드를 사용하고 있음을 표시 할 수 있기를 바란다. 때로는 하나의 메서드가 Handler.postDelayed을 사용하여 다른 스레드를 예약하기 때문에 thead 작업이 끝날 때까지 사용중인 플래그가 유지되도록하고 싶습니다.

지금까지는 공유 싱글 톤으로 쉽게 할 수있는 것처럼 들리지만,이 클래스들 각각 AlarmManagerBroadcastReceiver으로 확장되므로 공유 싱글 톤을 사용하면 실제로는 싱글 톤의 수명주기가 보장되지 않습니다. .

내가 생각할 수있는 유일한 해결책은 데이터베이스 또는 로컬 파일 시스템을 사용하는 것인데, 이는 매우 어리 석다. 따라서 AlarmManager에 의해 트리거되는 서로 다른 IntentService간에 동시 메서드를 플래그하는 다른 방법이 있습니까?

내가 클래스 A, 클래스 B 및 그래서 기본적으로 클래스 C

public class A extends IntentService { 
    public A(String name) { 
     super(name); 
     //initialise objects here 
    } 

    @Override 
    protected void onHandleIntent(Intent intent) { 
     //initialise objects that uses intent here 
    } 

    protected synchronized void methodA() { 
     //wait until flagB is free 
     flagA = in_use; //Flag something as being in use here 
     //change some objects here 
     Handler handler = new Handler(); 
     handler.postDelayed(new Runnable() { 
     @Override 
     public void run() { 
      //do some stuff with objects 
        flagB = not_in_use; //Flag something as being free here 
     } 
     }, (1000 * 45));// 45secs 
    } 

    protected synchronized void methodB() { 
     if (flagA == not_in_use) { 
      flagB = in_use; 
      //do some stuff with objects 
      flagB = not_in_use; 
     } 
     else { 
      //do something else 
     } 
} 

public class B extends IntentService { 
    public A(String name) { 
     super("B");//Super initializes everything 
    } 

    @Override 
    protected void onHandleIntent(Intent intent) {//This will run every 30 minutes 
     super.onHandleIntent(intent); 
     methodA(); 
    } 
} 


public class C extends IntentService { 
    public A(String name) { 
     super("C");//Super initializes everything 
    } 

    @Override 
    protected void onHandleIntent(Intent intent) {//This will run every 45 minutes 
     super.onHandleIntent(intent); 
     methodB(); 
    } 
} 

클래스 B와 C는 어떤 개인 클래스를 포함하지 않는 예를주고 싶은 선명한 이미지를 제공합니다. 내가하고 싶은 일은 위의 예와 같습니다. 문제는 정적 필드 일 뿐이며, 정적 필드는 메모리에 남아 있지 않을 수 있습니다. Android OS는 메모리를 저장하기 위해 비활성 상태 인 모든 것을 죽일 수 있기 때문입니다. 내가 원하는 무엇

답변

0

은 단순히 클래스 A의 생성자

중 하나에서 일부 동시성 검사가 생성자에 막지 마십시오 않는 것입니다. 객체 생성은 자유로운 조작이어야합니다. IntentService의 경우, 오브젝트가 메인 스레드 내에서 구성되기 때문에 아마 ANR을 얻게됩니다.

또는 onHandleIntent

예. 그것이 실제로 일어날 수있는 곳이기 때문에 그렇게 할 수있는 곳이 될 것입니다. 백그라운드 스레드 내에서 실행되므로 여기를 차단하는 것이 좋습니다.

클래스 (하위 클래스 포함)의 여러 인스턴스간에 동기화하려면 static을 사용해야합니다. 이는 복수 인스턴스가 "공유"하는 유일한 공통점이기 때문입니다.

앱의 수명주기를 외부에 동기화하는 것은 (아마도) 필요하지 않습니다. 앱 프로세스가 죽었다가 AlarmManager에서 다시 시작되면 새로운 싱글 톤을 사용할 수 있습니다. 이전에 일어난 일은 모두 죽었고 아무 일도 일어나지 않을 수 있습니다.예를 들어

이러한 서비스는 동일한 애플리케이션 프로세스 (추가 프로세스를 정의하지 않는다, 즉 모든 간단한 응용 프로그램) 내에서 실행되는 한 작동 않는

public class AService extends IntentService { 
    public AService() { 
     super("AService"); 
    } 

    @Override 
    protected void onHandleIntent(Intent intent) { 
     synchronized (AService.class) { 
      // magic happens here. 
     } 
    } 
} 


class BService extends AService { 
    void foo() { 
     synchronized(AService.class) { 
      // we can't be in here if another intentservice is within above block. 
     } 
    } 
} 

.class 객체를 사용하여 동기화. static은 앱의 어디에서나 액세스 할 수 있습니다.

예 : 파일 시스템은 서로의 객체에 전혀 액세스 할 수 없기 때문에 여러 프로세스가있는 경우 필요합니다.

외에도 synchronizedjava.util.concurrent에서보다 강력하고 향상된 동기화 방법을 찾습니다. 예 : 나는 THEAD 작업이 완료 될 때까지 플래그를 사용 상태로 유지되어 있는지 확인하려면

(synchronized 거의 비슷) `SemaphoreReentrantLock.

앱이 종료 된 경우 완료되지 않은 경우 다시 시작해야합니다. 따라서 앱의 수명이 다할 때까지 "작업 진행 플래그"를 유지하는 것은 의미가 없습니다. 실행 중일 때 static (예 : 싱글 톤)이 정상적으로 작동합니다.

+0

고마워요,하지만 그건 제가 묻고있는 것이 아닙니다. 내가 언급했듯이 Handler.postDelayed()가 있습니다. foo() 메소드의 경우 단순히 종료되지만 지연된 스레드는 다른 메소드 실행과 동시에 트리거 될 수 있습니다. –

+0

특정 조언을하기 위해 코드/스레드 구조 및 동시성 요구 사항을 이해할 수 없지만 일반적으로 모든 일반 동시성 유틸리티를 사용합니다. 'Handler.post..'는 일반적으로 (HandlerThread'를 사용하지 않는 한) 실행을 메인 쓰레드로 옮기며 결코 블록킹해서는 안됩니다. 그러니 조심해. 원하는 것을 설명하는 코드를 추가하십시오. – zapl

+0

예제를 추가했습니다. –