2017-08-25 7 views
0

複数のボタンがあるアプリケーションのメニューを作成しました。これらのボタンのうちの2つは、2つの別々のBluetoothメソッドを起動します問題は、これらのボタンを複数回押すと、それぞれのメソッドがBluetooth接続を管理しようとしているため(別の接続がその接続を閉じるかもしれない)、アプリケーションがクラッシュすることです。いずれかのメソッドが実行されていることを確認している間に、変数 '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); 
    } 

答えて

1

EDIT:要求されたように以下の方法のいずれかの追加されたコードは、(他の一つは、この文脈では無関係である2つの文字列を除いて、同一です)それはブール値で、semaphoreはここでトリックをすることができます。あなたが理由Androidのイベントシステムの動作方法で、onClick()のボタンを無効にすることで、この問題を解決することはできません

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

(milisで期間)

0

はこれを試してみてください。ユーザーがボタンを押すと、「クリック」イベントがイベント・キューに入れられます。ユーザーがボタンを2回連続して押すと(特にローエンドのデバイスやUIスレッドがビジーの場合)、2回の「クリック」イベントがキューに挿入されます。これを防ぐことはできません。

「クリック」イベントを処理した後に到着したイベントはすべて無視することを覚えておく必要があります(ユーザーが再びクリックできるようにするまで)。あなたはすでにこれを試したようですね。何が間違っているかわかるようにコードを投稿してください。


あなたのコードを見た後、私は次の入力があります。

mHandler場合は、メイン(UI)スレッドで作成されたが、あなたはあなたがネットワークをやっている、ここでのコードを持っているI/Oや問題を抱えています睡眠。あなたは絶対にメイン(UI)スレッドでそれを行うことはできません。このものがバックグラウンドスレッドで実行されていることを確認してください。これを行うには、独自のThreadを作成するか、Handlerがバックグラウンドスレッドで作成されていることを確認してください(HandlerThreadを参照)。

postDelayed()に電話する前に、ブール変数runningtrueに設定してください。投稿されたRunnableが完了すると、このフラグはfalseにクリアされます。これを確認するには、run()メソッド全体をtry/catchにラップし、finallyブロックの変数をクリアします。

lock()の場合、ブール変数runningtrueであるかどうか最初に確認します。そうであれば、ただちに戻る必要があります。これは、準備ができていないときに発生するクリックイベントを無視します。

+0

これは問題を解決するものではなく、アクションを遅らせるだけです。この問題を処理するには悪い方法です。@Patrick Michelの対処方法はこちら –

0

+0

上記の方法のコードを追加しました。 –

+0

ブール型の 'ok'は、あなたが提案した' running'と同じ目的を果たすことになっています。 –

+0

それから私は問題を理解していません。何がクラッシュしているのか、何が例外になったのか、何が動作していないのかを説明してください。 –

関連する問題