java - 安卓 :How to avoid to perform action simultaneously on togglebutton

标签 java android sockets

我正在开发一个应用程序,其中使用的数量为 ToggleButton .在ON和OFF操作上我正在执行不同的操作。它是基于家庭自动化的应用程序,因此按钮用于交流电、电视、灯光等。我有固定的字节数组来打开和关闭该设备。我正在使用套接字写入和读取这个字节数组。但我的问题是,当用户同时按下两个按钮时,按钮状态会闪烁,有时会向我显示 ANR 对话框。

这是我的代码 fragment :

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

更新2 这就是我在主线程中所做的设置状态

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

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

最佳答案

使用单线程执行器顺序发送数据。不要为每次数据传输创建新线程。

Executor executor = Executors.newSingleThreadExecutor();

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

所有的Runnables都会被一一执行。

关于java - 安卓 :How to avoid to perform action simultaneously on togglebutton,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14729355/

相关文章:

java - 如何使用 Spark 和 Java 来使用来自 Azure eventhub 的数据

java - Kerberos 如何获取主体或客户端名称?

android - 创建全局唯一的 Android 标识符

android - 全透明导航栏

java - AsyncTask 创建一个 Socket

sockets - 使用 TcpStream 强制非阻塞读取

java - JTextArea 不显示我告诉它的内容

java - 如何更改 Java Keystore(JKS) keystore 和别名密码以便它们正常工作

java - 如何在 Java 中比较日期并忽略时区

c++ - 客户端未通过套接字接收回数据 [传输端点已连接]