2014-01-29 110 views
1

我有一個擴展IntentService的類,讓我們說類A,然後我有2個更多的類作爲類B和類C,這些類擴展了類A.原因是因爲我想初始化所有內容A類使代碼將在B類和C所以B類和C的onHandleIntent方法被重用的樣子:IntentService併發

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

我想要做的就是簡單地做在A類的任何構造函數或onHandleIntent一些併發檢查。例如,當正在使用方法x(哪個類使用它無關緊要)時,我希望能夠標記此方法正在使用。有時一種方法使用Handler.postDelayed來安排另一個線程,所以我想確保該標誌在使用前一直保留,直到完成工作。

到目前爲止,它聽起來像它可以很容易地共享單身然而做,每個類都有自己的AlarmManager延伸BroadcastReceiver,所以使用的是共享單並未真正發揮一個單身的生命週期爲存在不保證。

我能想到的唯一解決方案是使用數據庫或本地文件系統,這聽起來很愚蠢。那麼是否有另一種方法來標記由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操作系統可以殺死任何不活躍節省內存的內存。

回答

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在應用程序中隨處可用。

使用例如外部鎖定如果你有多個進程,文件系統將是必需的,因爲它們根本無法訪問彼此的對象。

除​​之外,請查看java.util.concurrent以獲取更強大/更好的同步方式。例如。 `SemaphoreReentrantLock(大致相當於​​)

我想確保,直到THEAD工作完成的標誌是在使用中保持作爲。

如果你的應用程序被殺死了,你將不得不重新開始工作,如果它沒有完成。因此,在應用程序的整個生命週期中保留「工作進度標誌」是沒有意義的。而static(例如你的單身人士)在運行時可以正常工作。

+0

謝謝,但那不是我真正想問的。正如我所提到的,我有Handler.postDelayed()。 因此,對於foo()方法,它會簡單地結束,但稍後延遲的線程可能會與另一個正在運行的方法同時觸發。 –

+0

我不明白你的代碼/線程結構和concurreny要求給出任何具體的建議,但你通常會使用所有的常規併發實用程序。 'Handler.post..'通常會將執行移動到主線程中(除非您使用'HandlerThread'),並且不應該在那裏阻塞。所以要小心。嘗試添加一些解釋你想要做什麼的代碼。 – zapl

+0

我現在增加了一個例子。 –