2012-02-23 6 views
1

可能であればスレッドをブロックすることなく、アクセサリのInputStreamからバイトを読み取ろうとしています。AndroidでのスレッドブロッキングADK

通常、if available()read(buffer)呼び出しをラップしますが、available()は例外をスローします(read()がInputStreamで正常に動作しても)。

スレッドブロッキングを最小限に抑える方法はありますか?

EDIT:バックグラウンドで読み取りを行うために

IセットアップAsyncTask(私は拡張されたタスクのための本当のスレッドを使用する必要があります知っているが)、それは罰金っぽい動作します。

実際の質問は、「読み取り」コールによって常にバックグラウンドスレッドがブロックされることによるパフォーマンスの低下ですか?今は効果はありませんが、アプリケーションはすぐにかなり集中的になり、私はできるだけ軽いコミュニケーションをしたいと思います。

BufferedInputStreamは負荷をまったく軽減しますか?それはそれ自身のavailable()メソッドです。

+0

はなぜあなたのためだけに読み取り操作を処理するために、 'Thread'をスピンアップません:

これは、元の問題に対処すべきか?次に、処理するデータが実際にあるときはいつでも、他のオブジェクトにコールバックすることができます。 – aroth

答えて

1

、いや、read()呼び出しでブロックされたバックグラウンドスレッドを持つからも、パフォーマンスペナルティはありません。基本的には、バックグラウンドスレッドがスリープしているかのようです。

しかし、バックグラウンドスレッドを生成し続けると、それらのすべてが永久にブロックされた状態になり続けると、かなり重大なメモリリークが発生します。スピードなどの面でパフォーマンスが低下することはありませんが、最終的にアプリがクラッシュします。

したがって、バックグラウンドスレッドが最終的に終了することを確認することが重要です(または、少なくとも、既存のスレッドが終了しない場合は、コードが新しいスレッドを追加しようとしないことを保証することが重要です)。

public interface StreamDataHandler { 
    public void handleData(byte[] buffer, int numBytes); 
    public void readFailedWithError(Exception ex); 
} 

public class DataReader extends Thread { 
    private StreamDataHandler handler; 
    private InputStream input; 

    public DataReader(InputStream in, StreamDataHandler handler) { 
     super(); 
     this.input = in; 
     this.handler = handler; 
    } 

    @Override 
    public void run() { 
     int numRead = 0; 
     byte[] buffer = new byte[1024]; 
     try { 
      while ((numRead = input.read(buffer)) != -1) { 
       if (this.handler != null && numRead > 0) { 
        this.handler.handleData(buffer, numRead); 
       } 
      } 
     } 
     catch (Exception e) { 
      if (this.handler != null) { 
       this.handler.readFailedWithError(e); 
      } 
     } 
    } 
} 
+1

read()がストリームの終わりに達すると、それは-1を出すべきですが、私の問題は、データがなくなっても全く返ってこない、スレッドを無期限にブロックするということです。 – paulbovbel

+0

それで、 'input.close();'のようなことをする 'DataReader'に' timeout() 'メソッドを追加して、あなたの主なアクティビティスレッドで、' handleData() 'への呼び出しがなければ、時間の長さ。 – aroth

+0

それは私が必要なものです。ありがとう! – paulbovbel

0

RunnableまたはAsyncTaskを使用して、スレッドのブロック問題を回避できます。

Runnable

AsyncTask

別の方法としては、その例外がスローされている理由を調べることができます。あなたは例外をキャッチし、それが成功するまでTimerTaskが 'available()'を繰り返し呼び出すようにすることができます。あなたの編集した質問に対して

TimerTask

関連する問題