2017-05-24 7 views
0

非同期タスクを持ち、いくつかの異なるサービスから呼び出され、これらのサービスが定期的に実行される方法があります。私は、あるタスクが進行中であることを確かめたいのですが、タスクが終了しない限り他のタスクは呼び出せません。非同期タスクが一度だけ呼び出されるようにする方法

答えて

3
public class Helper { 

    public static void doSomethingAsync() { 
     new AsyncTask<String, Void, Integer>() { 
      @Override 
      protected void onPreExecute() { 
      } 

      @Override 
      protected Integer doInBackground(String... strings) { 
       //doing something 
      } 

      @Override 
      protected void onPostExecute(Integer resultCode) { 

      } 
     }.execute(); 
    } 

    public static void someOtherMethod(){ 

    } 
} 

AsyncTask.getStatus()が終了か否か、すなわち、タスクのステータスを与えます。

メンバ変数を宣言し

private static AsyncTask<String, Void, Integer> mTask; 

public static void doSomethingAsync() { 

    if(null != mTask && mTask.getStatus() != AsyncTask.Status.FINISHED){ 
     return; //Returning as the current task execution is not finished yet. 
    } 

    mTask = new AsyncTask<String, Void, Integer>() { 
     @Override 
     protected void onPreExecute() { 
     } 

     @Override 
     protected Integer doInBackground(String... strings) { 
      //doing something 
     } 

     @Override 
     protected void onPostExecute(Integer resultCode) { 

     } 
    }; 
    mTask.execute(); 
} 
+0

ご回答いただきありがとうございます。解決策を試しましたが、クラッシュしています。 'java.lang.ClassCastException:java.lang.Object []は' private static AsyncTask mTask'のjava.lang.String [] 'にキャストできませんこの行 – mSapps

+0

私は自分の答えを修正しました。宣言はAsyncTask でなければなりません。この変更を試してください – VishnuSP

2

は、すべてのサービスは、アプリケーション全体でアクセスすることができ、同じMutexへのアクセス権を持っていることを確認し、としてあなたの方法を変更します。非同期タスクにアクセスする前に今すぐ

、その後、として使用することができ

public class Mutex { 
    public void acquire() throws InterruptedException { } 
    public void release() { } 
    public boolean attempt(long msec) throws InterruptedException { } 
} 

次のように実行します。

try { 
    mutex.acquire(); 
    try { 
    // do something 
    } finally { 
    mutex.release(); 
    } 
} catch(InterruptedException ie) { 
    // ... 
} 

アンドロイドでhere


上で詳細をチェックします我々はSemaphoreを持っています。これについては、以下を

java.util.concurrent.Semaphore semaphore=new Semaphore(1); 

boolean isAvailable = semaphore.tryAcquire(); 
if(isAvailable){ 
    // Access AsyncTask 
} 

は一旦全てのアクションが行われている手順になり、onPostExecute

semaphore.release(); 
+0

ありがとう、代わりのアプローチ、私はそれを試してみましょう。 – mSapps

2

まであなたが「doSomethingAsync()」として同期方法せることによって、これを試すことができます。

public synchronized static void doSomethingAsync() { 
     new AsyncTask<String, Void, Integer>() { 
      @Override 
      protected void onPreExecute() { 
      } 

      @Override 
      protected Integer doInBackground(String... strings) { 
       //doing something 
      } 

      @Override 
      protected void onPostExecute(Integer resultCode) { 
      } 
     }.execute(); 
    } 

注:「ではなく、インスタンスのクラス」:ではなく、オブジェクトのクラスをロックし、それがキーワード静的意味するので、クラスをロックします

静的な同期メソッド。キーワードsynchronizedは、一度に1つのスレッドだけがメソッドにアクセスできることを意味します。 これは、「一度に1人だけがクラスにアクセスできます」という意味です。

+0

ご回答ありがとうございます、私は自分の質問を編集しました。ご覧のとおり、私はそのクラスにいくつかのメソッドがあります。あなたは '一度に一つしかクラスにアクセスできない 'と言っていたので、私の質問は、非同期タスクが実行されている間、このクラスの他のメソッドをアクセス不能にするでしょうか? – mSapps

+1

@mSapps:そのクラスの他のメソッドには、あなたが今どこからでも "doSomethingAsync()"が何かをブロックすることはありません。 –

+1

2つのサービスが実行されているとします。 Service1はdoSomethingAsync()メソッドにアクセスする機会を得て、その間にservice2はdoSomethingAsync()を呼び出そうとしますが、ロックはサービス1のスレッドによって既に獲得されているためアクセスはできません。そして、サービス2がdoSomethingAsync()に再びアクセスする機会を得た後、service1がそのロックを解放すると、それが理にかなってほしい。 –

0

が、これはあなたが同期の概念を参照する必要があり

0

をキューイングし、バックグラウンドスレッドで実行するサポートとして、それはuのを助ける代わりにIntentServiceを使用してみてください。
Link

関連する問題