应用程序在套接字上执行读/写操作时响应太频繁

时间:2013-01-22 10:36:08

标签: java android sockets

在我的应用程序中,我有12位数的字节数组,用于读取状态。写完这个数组后,我得到了不同按钮的状态。基于此响应,我将按钮设置为ON | OFF。我正在反复做这个任务。如果我把这个间隔时间设置得太短,即100毫秒并过于频繁地按下这些按钮,那么我的应用程序就会停止响应。

以下是代码段。

@Override
protected void onCreate(Bundle savedInstanceState) 
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main_activity);         
    getSharedSettings();

    fanDimmer1=(ToggleButton)findViewById(R.id.button_fan1);
    fanDimmer2=(ToggleButton)findViewById(R.id.button_fan2);
    dimmerLight1=(ToggleButton)findViewById(R.id.button_light1);
    dimmerLight2=(ToggleButton)findViewById(R.id.button_light2);


    fanDimmer1.setOnClickListener(this);
    fanDimmer2.setOnClickListener(this);
    dimmerLight1.setOnClickListener(this);
    dimmerLight2.setOnClickListener(this);

    if(ip.equals("") || port.equals(""))
    {
        new AlertDialog.Builder(MainActivity.this)
        .setTitle("Warning !")
        .setMessage("Please set IP and PORT first")
        .setIcon(android.R.drawable.ic_dialog_alert)
        .setNeutralButton("ok", null)
        .show();
    }
    else
    {
        new Thread(new Runnable() 
        {   
            @Override
            public void run()
            {
                Log.v(TAG, "openconnection");
                openConnection();
            }
        }).start();
        m_handler = new Handler();
        startRepeatingTask();

    }

}

public void openConnection()
{
    // TODO Auto-generated method stub
    try 
    {
        s = new Socket(ip, Integer.parseInt(port));
        i = s.getInputStream();
        iD = new DataInputStream(i);
        o = s.getOutputStream();
        oD = new DataOutputStream(o);
        Log.v(TAG, "openconnection 2");

    }
    catch (UnknownHostException e) {
        // TODO: handle exception
        Log.v("UnknowHostException :::::", "In Catch Block");
        e.printStackTrace();
    }
    catch (IOException e) {
        // TODO: handle exception
        Log.v("IOException :::::", "In Catch Block");
        e.printStackTrace();
    }
}

Runnable m_statusChecker = new Runnable() 
{
    @Override
    public void run() 
    {
        updateStatus();
        m_handler.postDelayed(m_statusChecker,100);
    }

    private void updateStatus() 
    {
        // TODO Auto-generated method stub
        Log.v("test", "1");
        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
                };

            o.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);
            txt_status.setText(status);
            Log.v(TAG, "status is ::"+status);


            char[] c=result.toCharArray();
            int count=0;
            for (int i=0;i<result.length();i++)
            {
                count++;
                char j=c[i];
                //Log.v(TAG, count+"::"+j);
                if(count==1)
                    toggleButton=dimmerLight1;
                else if(count==2)
                    toggleButton=fanDimmer2;
                else if(count==3)
                    toggleButton=fanDimmer1;
                else if(count==4)
                    Log.v(TAG, "Count 4 is 0");

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

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

    }
};

void startRepeatingTask() {
    m_statusChecker.run();
}

void stopRepeatingTask() {
    m_handler.removeCallbacks(m_statusChecker);
}

按下按钮,我正在执行此操作:

@Override
public void onClick(View v) 
{

    if(v.equals(fanDimmer1))
    {
        if (fanDimmer1.isChecked()) 
        {
            Toast.makeText(MainActivity.this, "Fan 1 is ON", Toast.LENGTH_SHORT).show();
            setByteArray((byte) 0x01, (byte) 0xff);
        } else 
        {
            Toast.makeText(MainActivity.this, "Fan 1 is OFF", Toast.LENGTH_SHORT).show();
            setByteArray((byte) 0x01, (byte) 0x00);
        }
    }

}

这是setByteArray()方法 我有24种这种按钮。

任何建议和建议都将受到赞赏 感谢

1 个答案:

答案 0 :(得分:1)

您正在从主线程中调用startRepeatingTask()

void startRepeatingTask() {
   m_statusChecker.run();
}

这意味着您的statusChecker也将在主线程中运行。

  • 要做的第一件事是更新updateStatus方法的代码并使用mHandler仅将ui-update代码发布到主UI线程

  • 接下来,你必须在另一个线程中运行statusChecker

要做到这一点,你有(至少)两个选择:

  1. [复杂的方式]做你自己的线程管理并在startRepeatingTask中写这样的东西

    void startRepeatingTask() { new Thread(m_statusChecker).start(); }

    调整停止方法(即使用监视器,无限循环和睡眠)

  2. [智能方式]从Android API中查看TimerTimerTask(以及this)并使用它们来实现您的需求。

  3. 修改

    专注于此代码:

    for (int i=0;i<result.length();i++)
            {
                count++;
                char j=c[i];
                //Log.v(TAG, count+"::"+j);
                if(count==1)
                    toggleButton=dimmerLight1;
                else if(count==2)
                    toggleButton=fanDimmer2;
                else if(count==3)
                    toggleButton=fanDimmer1;
                else if(count==4)
                    Log.v(TAG, "Count 4 is 0");
    
                if(j=='1')
                    toggleButton.setChecked(true);
                else
                    toggleButton.setChecked(false); 
            }
    

    此循环的效果将是:

    • 迭代0(如果有):将检查或取消选中dimmerLight1
    • 迭代1(如果有):将检查或取消选中fanDimmer2
    • 迭代2(如果有):将检查或取消选中fanDimmer1
    • 迭代3(如果有):将检查或取消选中fanDimmer1
    • 迭代4(如果有):将检查或取消选中fanDimmer1
    • 迭代5(如果有):将检查或取消选中fanDimmer1
    • ...(将在循环结束前检查或取消选中fanDimmer1)

    我很确定这不是你需要的。 (除非result.size()总是3,但在任何其他情况下:这段代码会产生奇怪的东西)

    您可以这样做:

    //assuming buttons is a ToggleButton[32] populated with all your buttons in the correct order
    for (int i=0;i<result.length();i++)
        {
            buttons[i].setChecked(c[i]=='1'); 
        }