2012-04-22 9 views
0

私は、サーバにデータを読み込んで送信するために2つのスレッドを使用するアプリケーションを開発中です。各スレッドはwhileループを実行します。 queは、サーバに送るためにdequedされるコマンドのqueを保持します。このようにして、私は多数のコマンドを整列させることができます。これらのコマンドは、dequedされ、1つずつサーバに送られます。ネットワークデータの送信に使用されるAndroidスレッドの最適化

コマンドの送信者は、読み出しループが結果としてそのような

 while (inputStream.read() > -1) 

ように見え、アプリケーションが携帯電話の処理能力の50%を占めてしまうような

class writeThread extends AsyncTask<Object, Object, Object> 
{ 
    byte[] buffer; 
    LittleEndianDataOutputStream outputStream; 
    @Override 
    protected void onPreExecute() 
    { 

    } 
    @Override 
    protected Object doInBackground(Object... params) 
    { 
     try 
     { 
      buffer = new byte[4096]; 
      outputStream = new LittleEndianDataOutputStream(dataHolder.connection.getOutputStream()); 

      try 
      { 
       dataHolder.flags latestFlag; 
       while (true) 
       { 
        try 
        { 
         latestFlag = dataHolder.sendFlags.remove(); 
         ByteBuffer sendBytes = ByteBuffer.allocate(128); 
         sendBytes.order(ByteOrder.LITTLE_ENDIAN); 
         switch (latestFlag) 
         { 
          case sendDataRequest: 
           sendBytes.putInt(20); 
           outputStream.write(sendBytes.array()); 
           break; 
          case getSelectedData: 
           sendBytes.putInt(21); 
           sendBytes.put(dataHolder.latestSelected.getBytes()); 
           outputStream.write(sendBytes.array()); 
           break; 
          case disconnect: 
           sendBytes.putInt(254); 
           sendBytes.put(dataHolder.latestSelected.getBytes()); 
           outputStream.write(sendBytes.array()); 
           break;          

         } 


        } 
        catch (NoSuchElementException ex){} 
       } 
      } 
      catch (IOException ex) {} 

     } 
     catch (Exception ex){}; 
     return null; 

    } 


} 

通りです。ソケットリスニングとデータ送信を最適化する方法に関する提案はありますか?

注:キューの空きがないかどうかを確認するif文の代わりに、キューのtry catchを使用しています。私は投げているエラーが最適化を助けていないと確信していますが、私はそれがプロセッサを50%に押し上げるとは思わないのです。もう情報が必要な場合はお知らせください。

+0

Lol私はちょうど私が未使用の4kbのバッファを周りに座っていることを知った。前のコードから残っていなければなりません。 –

答えて

0

あなたの実装での問題は、基本的にビジーウェイトを実行していることです。何も送信しなければ、すぐに例外ハンドラに行き、再び試行します。そのため、そのコアのすべてのCPUを占有します。

代わりに、イベントが利用可能になるまで待つ方法があります。 HandlerThreadを作成し、そのスレッドに関連付けられたハンドラを使用してデータストリームへの書き込みを処理することをお勧めします。

HandlerThread handlerThread = new HandlerThread("blah"); 
handlerThread.start(); 
Handler handler = new Handler(handlerThread.getLooper()) { 
    public boolean HandleMessage(Message msg) { 
     switch (msg.what) { 
      case sendDataRequest: 
       ... 
      case getSelectedData: 
       ... 
      case disconnect: 
       ... 
     } 
    } 
} 

そして、あなたはあなたのdataHolder.sendFlagsコレクションArrayBlockingQueueを行った場合、あなたは、適切なIDとデータとのメッセージを作成し、handler.sendMessage()

(おそらくより簡単かつ)代わりにハンドラに送信します何かが利用可能になるまで(なし)で次の要素を削除すると、が実行されずにすべてを占めるようになります(ArrayListなどを推測しています)利用可能なCPU時間)

+0

新しいハンドラ(handlerThread.getLooper())のpublic boolean HandleMessage(Message msg)は一部ですか?オープニングブラケットの前に閉じています。私は高校時代から何もメジャーなことにJavaを使っていませんでした。私は少し乾いていますので、初期化を理解していないかもしれません。 –

+0

これは匿名のクラスとして知られているものです。これは同時に、Handlerの新しいサブクラスと、そのサブクラスの新しいインスタンスを作成し、Handler.HandleMessageをオーバーライドします。例えば、http://docstore.mik.ua/orelly/java-ent/jnut/ch03_12.htm – JesusFreke

+0

ああ、興味深いことに、私はJavaでそれを見たとは思わない。私はそれを({})で見るのに慣れています。私は何かを理解していないのですか? –

関連する問題