按下按钮时执行停止方法

时间:2017-08-25 10:31:43

标签: android

我为具有多个按钮的应用程序编写了一个菜单。其中两个按钮触发两种不同的蓝牙方法。问题是,在多次快速按下这些按钮时,应用程序崩溃,因为每种方法都试图管理蓝牙连接(而另一种方法可能会关闭该连接)。我已经尝试在任何方法运行时设置变量'true'并检查它但它不起作用。我不确定系统是否在不同的线程中同时运行每个方法,或者它是否将方法排入队列。

问题是当另一个方法执行时,我是如何停止按下按钮来运行方法的?执行一个完成后我不需要它排队,我只需要它被阻止。

编辑:根据要求添加了以下方法之一的代码(另一个是相同的,除了两个字符串,在此上下文中无关紧要):

public void lock(View button_lock) {
        if(ok)
            return;
        if (btAdapter == null) {
            Context context = getApplicationContext();
            CharSequence text = "Bluetooth not supported!";
            int duration = Toast.LENGTH_SHORT;
            Toast toast = Toast.makeText(context, text, duration);
            toast.show();
            return;
        }
        else if (address == null) {
            Context context = getApplicationContext();
            CharSequence text = "Please pair your phone with SmartLock.";
            int duration = Toast.LENGTH_SHORT;
            Toast toast = Toast.makeText(context, text, duration);
            toast.show();
            return;
        }
        if (!btAdapter.isEnabled()) {
            btAdapter.enable();
            ok=true;
        }
        mHandler.postDelayed(new Runnable() {public void run() {
            BluetoothDevice device = btAdapter.getRemoteDevice(address);
            ParcelUuid[] uuids = device.getUuids();
            BluetoothSocket mmSocket;
            try {
                mmSocket = device.createRfcommSocketToServiceRecord(uuids[0].getUuid());
                mmSocket.connect();
                OutputStream out = mmSocket.getOutputStream();
                InputStream in = mmSocket.getInputStream();
                out.write("1".getBytes());
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                in.close();
                out.close();
                mmSocket.close();
                in = null;
                out = null;
                mmSocket = null;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }}, 1000);
        Context context = getApplicationContext();
        CharSequence text = "Bike locked!";
        int duration = Toast.LENGTH_SHORT;
        Toast toast = Toast.makeText(context, text, duration);
        toast.show();
        mHandler.postDelayed(new Runnable() {public void run() {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            btAdapter.disable();
            ok=false;
        }}, 2000);
    }

3 个答案:

答案 0 :(得分:1)

正如您已经使用布尔值尝试的那样,semaphore可以在这里做到这一点。

答案 1 :(得分:1)

由于Android事件系统的工作方式,您无法通过禁用onClick()中的按钮来解决此问题。当用户按下按钮时,“click”事件将排队到事件队列。如果用户快速连续按下按钮两次(特别是在低端设备上或当UI线程忙时),则会在队列中插入2个“单击”事件。你不能阻止这种情况。

您需要做的是记住您已经处理了“点击”事件并忽略了之后到达的任何事件(直到您希望允许用户再次点击)。听起来你已经尝试过了。请发布您的代码,以便我们查看错误。

看到你的代码后,我有以下输入:

如果在主(UI)线程上创建了mHandler,则表示您遇到问题您在这里有代码正在进行网络I / O和休眠。你绝对不能在主(UI)线程上这样做。确保这些东西在后台线程中运行。要执行此操作,请创建自己的Thread或确保在后台线程上创建Handler(请参阅HandlerThread作为示例)。

在致电postDelayed()之前,请将布尔变量running设置为true。发布的false完成后,此标志应清除为Runnable。要确保这一点,请将整个run()方法包装在try/catch中,并在finally块中清除变量。

lock()中,首先检查布尔变量running是否为true。如果是,您应该立即返回,这将忽略您尚未准备好的点击事件。

答案 2 :(得分:0)

试试这个:

    bluetoothMethod();
    bluetoothButton.setEnabled(false);
    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            bluetoothButton.setEnabled(true);
        }
    }, duration);

(持续时间以毫秒为单位)