2013-02-06 22 views
0

我正在開發一個應用程序,其中我使用的號碼是ToggleButton。on ON和OFF操作我正在執行不同的操作。它的家庭基於自動化的應用程序,所以按鈕用於交流,電視,光等我有固定的字節數組打開和關閉此設備。我正在寫和閱讀這個字節數組使用套接字。但我的問題是,當用戶同時按下兩個按鈕,然後按鈕狀態被眨眼,有時它會顯示我一個ANR對話框。Android:如何避免在togglebutton上同時執行動作

這裏是我的代碼片段:

@Override 
public void onClick(View v) 
{ 
    if(v.equals(fanDimmer1)) 
    { 
     if (fanDimmer1.isChecked()) { 
     setByteArray((byte) 0x01, (byte) 0xff); 
     } else { 
     setByteArray((byte) 0x01, (byte) 0x00); 
     } 
    } 
    else if(v.equals(fanDimmer2)) 
    { 
     if (fanDimmer2.isChecked()) { 
     setByteArray((byte) 0x02, (byte) 0xff); 
     } else { 
     setByteArray((byte) 0x02, (byte) 0x00); 
    } 
    } 
} 

這裏是SetByteArray()方法。

private synchronized void setByteArray(final byte a, final byte b) 
    { 
     new Thread (new Runnable() { 

      @Override 
      public void run() { 
       // TODO Auto-generated method stub 
       try { 

        byte[] data2 = new byte[1024], packet2 = 
         { 
          (byte) 0x00,(byte) 0x00,(byte) 0x00, 
          (byte) 0x00,(byte) 0x00,(byte) 0x06, 
          (byte) 0x01,(byte) 0x05,(byte) 0x00, 
          a, b,(byte) 0x00 
         }; 

        //o.write(packet2); 
        write(packet2); 
        i.read(data2, 0, 1024); 
       } catch (UnknownHostException e) { 
        e.printStackTrace(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 

      } 
     }).start(); 
    } 

更新:

這裏是write()方法

public synchronized void write(byte[] pkg) 
{ 
     try { 
      o.write(pkg); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
    } 

初始化:

s = new Socket(ip, Integer.parseInt(port)); 
i = s.getInputStream(); 
o = s.getOutputStream(); 

UPDATE2 這就是我DOI納克主線程設置狀態

Runnable m_statusChecker = new Runnable() 
{ 
    @Override 
    public void run() 
    { 
     if (count == 0) { 
      updateStatus(); 
      count = 1; 
     } else { 
      updateStatus1(); 
      count = 0; 
     } 
     m_handler.postDelayed(m_statusChecker,Integer.parseInt(interval)); 
    } 

    private synchronized void updateStatus() 
    { 
     // TODO Auto-generated method stub 
     try { 
      byte[] data1 = new byte[1024], packet1 = 
      { 
       (byte) 0x00,(byte) 0x00,(byte) 0x00, 
       (byte) 0x00,(byte) 0x00,(byte) 0x06, 
       (byte) 0x01,(byte) 0x01,(byte) 0x00, 
       (byte) 0x00,(byte) 0x00,(byte) 0x19 
      }; 

      write(packet1); 
      i.read(data1, 0, 1024); 

      byte_to_hex = ConversionMethods.bytesToHex(data1).substring(18, 26); 

      char[] arr = byte_to_hex.toCharArray(); 
      for (int i = 0; i < arr.length - 1; i += 2) 
      { 
       char temp = arr[i]; 
       arr[i] = arr[i + 1]; 
       arr[i + 1] = temp; 
      } 

      swapped_result=new String(arr); 
      result = ConversionMethods.hexStringToNBitBinary(swapped_result, 32); 

      int counter = 0; 
      for(int i=0; i<result.length(); i++) 
      { 
       if(result.charAt(i) == '1') 
       { 
        counter++;   
       } 
      } 
      status=Integer.toString(counter); 
      runOnUiThread(updateButtons); 

     } catch (UnknownHostException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

    } 
} 

updateButtons()

Runnable updateButtons=new Runnable() { 

    @Override 
    public void run() { 
     // TODO Auto-generated method stub 
     txt_status.setText(status); 
     /*Log.v(TAG, "status is ::"+status);*/ 
     char[] c=result.toCharArray(); 
     int count=0; 
     for (int i=0;i<24;i++) 
     { 
      count++; 
      char j=c[i]; 
      Log.v(TAG, count+"::"+j); 
      if(count==1) 
       toggleButton=dimmerLight1; 
      else if(count==2) 
       toggleButton=dimmerLight2; 
      else if(count==3) 
       toggleButton=dimmerLight3; 
      else if(count==4) 
       toggleButton=dimmerLight4; 
      else if(count==5) 
       toggleButton=dimmerLight5; 
      ............ 
      ............ 

      if(j=='1') 
       toggleButton.setChecked(true); 
      else 
       toggleButton.setChecked(false); 
     } 

    } 
}; 

如何處理這種情況。我有24這種ToggleButtons。如果有人之前有這個問題,然後與我分享。

任何幫助和想法將不勝感激。
謝謝

+1

你是如何得出結論的:你需要用'equals()'來比較'v'? - 什麼是「我」,爲什麼「o」被註釋掉? - 您是否意識到,當用戶按下按鈕時可能會並行啓動多個線程? 'data2'發生了什麼? - 'synchronized'並沒有按照我認爲的那樣做。 ;) –

+0

在您正在處理時禁用按鈕,並在完成後啓用它。此外,您可以始終取消正在執行的一個,並啓動另一個。 – Atrix1987

+0

@ClassStacker我已更新的問題,請檢查 – juned

回答

1

使用單線程執行程序按順序發送您的數據。不要爲每個數據傳輸創建新的線程。

Executor executor = Executors.newSingleThreadExecutor(); 

private void setByteArray(final byte a, final byte b) { 
    executor.execute(new Runnable() { 
     public void run() { 
      // your code here 
     } 
    }); 
} 

所有的Runnables將被逐一執行。

+0

所以我應該執行我的'setByteArray()'方法使用執行權? – juned

+0

已更新的答案。這應該工作,如果你的寫/讀同步工作。 – Leonidos

+0

謝謝,它改進了性能,但尚未解決問題! – juned

0

隨着對你打算做什麼的一些理解,我建議如下。

  • 在您的活動中有一組完整的值。
  • 使您的點擊事件處理程序修改值的數組,然後
  • 之後,開始一個新的AsyncTask即時創建。
  • 在該AsyncTask的onPreExecute(在主UI線程上執行)中,禁用所有複選框。
  • 在AsyncTask的doInBackground中,發送值並再次接收它們。
  • onPostExecute中,根據新接收的數據設置所有複選框的狀態,然後啓用它們。

如果這不足夠響應,您需要決定如何處理設置衝突。我認爲這取決於環境的性質。無論哪種方式,該方案可以很容易地擴展:

  • onPreExecute,複製當前值,但不要禁用複選框。
  • doInBackground,接收數組的另一個副本中的值。
  • onPostExecute(在主UI線程上執行)中,將接收到的vlaues與複選框的值進行比較。如果它們不相同,則啓動一個新的AsyncTask以發送代表用戶設置的值。

這實現了衝突解決方案的策略,這意味着用戶的設置應該覆蓋反饋。如果需要另一種策略,您可以瞭解如何實施它。

+0

感謝您的回答我會盡力實施這種方式 – juned

相關問題