2016-08-26 2 views
1

Я хочу вызвать метод sendDate при нажатии кнопки. Но, к сожалению, я получаю бесконечный цикл, и мое приложение замерзает. Может быть, я могу попробовать его с обработчиком, но я не уверен.Повторно вызовите метод при нажатии кнопки

controllerButton.setOnTouchListener(new OnTouchListener() { 
    @Override 
    public boolean onTouch(View view, MotionEvent motionEvent) { 
     if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) { 
      while (motionEvent.getAction() == MotionEvent.ACTION_DOWN) { 
       if (liftStatus == LIFT_IS_UP) { 
        sendData(3); 
       } else if (liftStatus == LIFT_IS_DOWN) { 
        sendData(1); 
       } 
      } 

      if (liftStatus == LIFT_IS_UP) { 
       sendData(4); 
       return true; 
      } else if (liftStatus == LIFT_IS_DOWN) { 
       sendData(2); 
       return true; 
      } 

      return false; 
     } 
    } 
}; 

SendData Метод

Метод является контроль лифта, который через Bluetooth LE подключен

private void sendData(int command){ 
     if (myBluetoothGattCharacteristic != null) { 
      switch(command) { 
       case 1: 
        myBluetoothGattCharacteristic.setValue("Lift_UP_START"); 
        break; 
       case 2: 
        myBluetoothGattCharacteristic.setValue("Lift_UP_STOP"); 
        break; 
       case 3: 
        myBluetoothGattCharacteristic.setValue("Lift_DOWN_START"); 
        break; 
       case 4: 
        myBluetoothGattCharacteristic.setValue("Lift_DOWN_STOP"); 
        break; 
       default: 
        return; 
      } 
      myGatter.writeCharacteristic(myBluetoothGattCharacteristic); 
     } 
    } 
+0

Вы можете попробовать использовать 'onClickListener' вместо 'onTouchListener'. Это обычный прослушиватель для нажатия кнопки. – Marcel50506

+0

@ Marcel50506 как бы решить эту проблему? – Dominic

+0

Во-первых, не делайте трудоемких действий в потоке пользовательского интерфейса. Запустите его в отдельном потоке. Во-вторых, исследуйте бесконечный цикл. Даже вне основного потока это не должно происходить. – mhenryk

ответ

0

Точно. Я бы тоже сделал это с обработчиком.

private Handler mHandler = new Handler(); 
private final Runnable mConnectionCheck = new Runnable() { 
    @Override 
    public void run() { 
     mHandler.postDelayed(this, 1000); 
    } 
}; 

public void sendData(int value) { 
    mHandler.post(mConnectionCheck); 
} 
2

Проблема заключается ваш while statement потому что как только вы получили событие движения с ACTION_DOWN события, значение motionEvent.getAction() будет таким же навсегда до конца этой функции, следовательно, вы оказались в ловушке в вас во время цикла и значение событие никогда не изменяется в вашей петле, поэтому бесконечный цикл

while(motionEvent.getAction() == MotionEvent.ACTION_DOWN){ // unwanted while , remove this while loop , use if-else or switch , 
//like if(motionEvent.getAction() == MotionEvent.ACTION_DOWN){ 
// check your up and down} 

     if (liftStatus == LIFT_IS_UP){ 
      sendData(3); 
     }else if (liftStatus == LIFT_IS_DOWN){ 
      sendData(1); 
     } 
    } 
1

Как уже упоминалось, вы не можете иметь цикл while внутри вашего слушателя касания. Это не позволяет обратному каналу возвращать и зависеть от вашего ui. Начиная от кода, который вы в курсе, я хотел бы использовать Handler, который держит исполняющих Runnable:

 btn.setOnTouchListener(new View.OnTouchListener() { 
      @Override 
      public boolean onTouch(View view, MotionEvent motionEvent) { 
       if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) { 
        handler.post(new Runnable() 
        { 
         @Override 
         public void run() 
         { 
          handler.post(new MyRunnable({some_value})); 
         } 
        }); 

        return false; 
       } 
       else 
       { 
        handler.removeCallbacksAndMessages(null); 
        return false; 
       } 
      } 
     }); 

и в классе, где вы используете его:

private Handler handler; 

public class MyRunnable implements Runnable 
{ 
    private int value; 

    public MyRunnable(int value) 
    { 
     this.value = value; 
    } 

    public void setValue(int value) 
    { 
     this.value = value; 
    } 

    @Override 
    public void run() 
    { 
     sendData(value); 
     <check if you need to change this.value> 
     handler.post(this); 
    } 
} 
Смежные вопросы