2014-09-25 39 views
0

以下代碼摘自here疑難解答藍牙輸入和輸出android

有人能請深入解釋這是如何工作的嗎?

這個處理程序是什麼,它有什麼作用?

實施條件如何實施?

循環如何繼續?

我對代碼的工作原理有非常粗略的理解,如果你能幫我解決問題,那對我非常有利。謝謝。

{ 
    final Handler handler = new Handler(); 
    final byte delimiter = 10; //This is the ASCII code for a newline character 

    stopWorker = false; 
    readBufferPosition = 0; 
    readBuffer = new byte[1024]; 
    workerThread = new Thread(new Runnable() 
    { 
     public void run() 
     {     
      while(!Thread.currentThread().isInterrupted() && !stopWorker) 
      { 
       try 
       { 
        int bytesAvailable = mmInputStream.available();       
        if(bytesAvailable > 0) 
        { 
         byte[] packetBytes = new byte[bytesAvailable]; 
         mmInputStream.read(packetBytes); 
         for(int i=0;i<bytesAvailable;i++) 
         { 
          byte b = packetBytes[i]; 
          if(b == delimiter) 
          { 
           byte[] encodedBytes = new byte[readBufferPosition]; 
           System.arraycopy(readBuffer, 0, encodedBytes, 0, encodedBytes.length); 
           final String data = new String(encodedBytes, "US-ASCII"); 
           readBufferPosition = 0; 

           handler.post(new Runnable() 
           { 
            public void run() 
            { 
             myLabel.setText(data); 
            } 
           }); 
          } 
          else 
          { 
           readBuffer[readBufferPosition++] = b; 
          } 
         } 
        } 
       } 
       catch (IOException ex) 
       { 
        stopWorker = true; 
       } 
      } 
     } 
    }); 

    workerThread.start(); 
} 

void sendData() throws IOException 
{ 
    String msg = myTextbox.getText().toString(); 
    msg += "\n"; 
    mmOutputStream.write(msg.getBytes()); 
    myLabel.setText("Data Sent"); 
} 

回答

0

一定要知道線程是什麼,或者我可以澄清它。 您應該知道,您提供的代碼正在定義您的workerThread。一旦在該線程上調用start(),所有寫入run方法的內容都將在另一個線程中運行。在run方法之前定義的所有變量都在主線程中定義。處理程序也是如此。

Handler旨在連接2個線程。您可以在一個線程(這裏是run方法之前的主線程)中定義它,並且在另一個線程(在run方法中)中使用它來在定義它的線程中執行一些操作。因此,在你的代碼,你叫

handler.post(new Runnable() 
          { 
           public void run() 
           { 
            myLabel.setText(data); 
           } 
          }); 

從的WorkerThread,所以

myLabel.setText(data); 

將從主線程(其中被實例化處理程序的線程)執行。

它爲什麼這樣做?因爲.setText()不能從主線程以外的其他線程調用,因爲它正在繪製某些內容。

循環檢查,而該線程未被中斷(由Android或別的東西),而且你的布爾stopWorker沒有被修改,那麼,有沒有異常,同時從InputStream裏讀入拋出

嘗試{} catch(){}只是一種管理異常的方法。

.available()方法通過調用.read()方法爲您提供可以從inpuStream讀取的字節數。如果有一些可用的字節(所以如果你的手機從連接的設備收到的東西),然後它讀取它。

讀取方法的工作方式如下:將一個字節數組作爲參數,它將從輸入流中獲取可用字節並將它們放入字節數組中。

然後處理接收的字節數...

但對我來說這不是一個有效的解決方案,因爲該線程將循環速度非常快,而.read()是一個阻塞方法,所以所有的部分檢查檢查是否有可用的字節是無用的,甚至效率低下。 .read()會使線程休眠,直到新字節可用,從而釋放資源。也許還有另一個原因,爲什麼代碼這樣做,但我沒有看到它。

希望這是明確的。