0

我正在开发一个应用程序,在该应用程序中我使用了多个ToggleButton .on ON 和 OFF 动作,我正在执行不同的动作。它基于家庭自动化的应用程序,所以按钮适用于 AC、TV、Light 等。我有固定的字节数组来打开和关闭这个设备。我正在使用套接字写入和读取这个字节数组。但我的问题是当用户同时按下两个按钮时,按钮状态会闪烁,有时它会向我显示 ANR 对话。

这是我的代码片段:

@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 这是我在主线程中设置状态的方法

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();
        }

    }
}

更新按钮()

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。如果有人在此之前遇到过这个问题,请与我分享。

任何帮助和想法将不胜感激。
谢谢

4

2 回答 2

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 都会被一一执行。

于 2013-02-06T12:46:02.603 回答
0

在对您打算做什么有所了解后,我建议以下内容。

  • 在您的活动中拥有完整的值数组。
  • 使您的单击事件处理程序修改值数组并
  • 之后,开始一个新的AsyncTask动态创建。
  • onPreExecute该 AsyncTask(在主 UI 线程上执行)中,禁用所有复选框。
  • doInBackgroundAsyncTask 中,发送值并再次接收它们。
  • onPostExecute中,根据新收到的数据设置所有复选框的状态,然后启用它们。

如果这反应不够灵敏,您需要决定如何处理设置冲突。我认为这取决于环境的性质。无论哪种方式,该方案都可以轻松扩展:

  • onPreExecute中,复制当前值,但不要禁用复选框。
  • doInBackground中,接收另一个数组副本中的值。
  • onPostExecute(在主 UI 线程上执行)中,将收到的值与复选框的值进行比较。如果它们不相等,则触发一个新的 AsyncTask 以发送代表用户设置的值。

这实现了冲突解决策略,这意味着用户的设置应该覆盖反馈。如果需要其他策略,您可能会知道如何实施它。

于 2013-02-06T14:19:58.943 回答