2016-06-23 3 views
0

私はjavaとandroidを初めて使っています。 メインUIスレッドのサービスで次の機能を実行しています。UIスレッドをブロックしないようにループを書く方法は?

public void startSession() { 
    Log.d(TAG, "startSession()"); 
    sessionStartRequestCompleted = false; 
    int c =0; 
    do { 
     Log.d(TAG, "startSession() - Tyring again #" + c); 
     writeCharacteristic(
       characteristicMap.get(ShsServiceConstants.SH_GATT_SVC_SESSION_TOGGLER_CHARACTERISTIC_UUID), 
       ShsServiceConstants.SESSION_TOGGLER_CHAR_SESSION_START_OPCODE); 
     try { 
      Thread.sleep(500); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
     int timeout = 0; 
     sessionStartStatus = false; 
     checkSessionStatus(); 
     while (!sessionStartStatus && timeout < 10) { 
      timeout++; 
      try { 
       Thread.sleep(100); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 
     if (timeout >= 10) { 
      Log.d(TAG, "StatusCheckTask Timed Out waiting for result"); 
      //fireNextShsGattRequest(); 
     } 
     c++; 
    } while (!sessionStartRequestCompleted); 
} 

しかし、この関数を呼び出すとUIスレッドがブロックされます。どのように私はUIスレッドをブロックしないようにこの関数を書くことができますが、フラグのチェックを行います。

フラグはonCharacteristicRead内で設定されています。

+1

AsyncTaskを使用するか、コード内で新しいスレッド()を作成してください –

+0

[Androidデベロッパー](https://developer.android.com/training/index.html)のウェブサイトは、[偉大な記事](https://developer.android。 com/guide/components/processes-and-threads.html#WorkerThrea ds)を実行する方法について説明します。 Sidenote:なぜ "Thread.sleep"と呼ぶのかを書かなければなりません。 – Fildor

+0

ユーザーが目にする可能性があるUIスレッドで長時間実行されるコードがある場合(UIは応答しない、「ロックアップ」)、唯一の答えは、(a)コードを高速化する(b)**そのワークロードを別のスレッドに移動する**。作業を別のスレッドに移すさまざまな方法がありますが、そのうちのいくつかは以下の回答で説明しています。 –

答えて

0

サービス中の操作を実行するためにハンドラスレッドを使用します。

0

new AsyncTask<Void, Void, Void>(){ 
    protected Void doInBackground(){ 
    //your while loop 
    return null; 
    } 

    protected void onPostExecute(){ 
    //here goes what you need to update when task end 
    } 
} 
0

内のループを巻き、私はRxJavaをチェックアウトすることをお勧めします。アンドロイドでは、とにかくそれを使用することになります、それはアンドロイドで最高の非同期アプローチの一つです。

0

ループ内でThread.yield()メソッドを定期的に使用します。ループにはブロッキング状態がないので、他のスレッドがCPU時間を取得できるように、生成する方が良いです。しかし、現代のJavaコンパイラは自動的に定期的に実行されるため、常に1つのスレッドしか使用されません。

+0

良い答えですが、別の質問です。この質問には、メイン(UI)スレッドで実行されているコードがあります。 'yield 'を呼び出すことはここで助けにならず、UIを反応的にしません。 'yield'メソッドは、別の*スレッドで呼び出さなければなりません。これはタイトなループであり、CPUをあまりにも多く使うかもしれません。 –

0

IntentServiceは新しいバックグラウンドスレッドで実行されるため、代わりに使用できます。もう1つの解決方法は、ランクのためにRxJavaライブラリを使用することです。 RxJavaで はSchedulers.computation()スケジューラ

関連する問題