2017-12-14 43 views
0

私はスマートウォッチ用のスタンドアロンアプリを開発しました。Touchが少なくとも3秒間続いたかどうかを検出し、場合。 (MotionEventがアップしているときfalseに設定されているシンプルなブール状態とHandlerPostDelayedアクション)removeCallbacks()は、ハンドラ内の指定されたRunnableを削除していないようです

private int longClickDuration = 3000; 
private boolean isLongPress = false; 
static Runnable longTouchRunnable; 

mContainerView.setOnTouchListener(new View.OnTouchListener() { 
      @Override 
      public boolean onTouch(View v, MotionEvent event) { 

       longTouchRunnable = new Runnable() { 
        @Override 
        public void run() { 
         if (isLongPress) { 
          Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE); 
          long[] vibrationPattern = {0, 500, 50, 300}; 
          //-1 - don't repeat 
          final int indexInPatternToRepeat = -1; 
          vibrator.vibrate(vibrationPattern, indexInPatternToRepeat); 
          // set your code here 
          setStateStarting(); //Block the GUI, only one click and waiting for tablet 
          presenter.onStartClick(); 
          Log.d("Long","LONG CLICK PERFORMED"); 
          // Don't forgot to add <uses-permission android:name="android.permission.VIBRATE" /> to vibrate. 
         } 

        } 
       }; 

       switch (currentState) { 
        case START: { 
         if (event.getAction() == MotionEvent.ACTION_DOWN) { 
          isLongPress = true; 
          Log.e("Long touch","Start"); 
          myUIHandler.postDelayed(longTouchRunnable, longClickDuration); 
         } else if (event.getAction() == MotionEvent.ACTION_UP) { 
          isLongPress = false; 
          myUIHandler.removeCallbacks(longTouchRunnable); 
          Log.e("Long touch", "Stop"); 
         } 
         return true; 
        } 
       } 
       return false; 
      } 


     }); 

私の問題: すべてが完璧に動作をすることを期待する。ここ

は、私が使用するコードです Runnableは必要なときに削除されていないようです。 - >ビューで2回すばやくクリックしてから3回目に押して保持している場合(3秒後に表示されるのブール値状態は true)、3回実行します。 > Runnableタスクは ACTION_UPイベントで削除されませんでした。

情報:予想通りのメッセージのデバッグはプロンプトです...

はどうすれば適切にhandlerにpostdelayedたRunnableを破壊することができますか?

おかげで、それは言うremoveCallbacksAndMessagesのためのドキュメントで

答えて

0
handler.removeCallbacksAndMessages(null); 

...

は、コールバックの保留中の投稿を削除し、OBJトークンでメッセージを送りました。トークンがNULLの場合、すべてのコールバックとメッセージは削除されます。

removeCallbacksは、ペンディングメッセージ(ランナブル)のみを停止します。あなたの実行可能ファイルが既に起動している場合は、停止しません(少なくともこの方法ではありません)。

また、あなたはRunnableをクラスを拡張し、このようにそれをキルスイッチのいくつかの種類を与えることができます:

public class MyRunnable implements Runnable 
{ 
    public boolean killMe = false; 

    public void run() 
    { 
     if(killMe) 
     return; 

     /* do your work */ 
    } 

    public void killRunnable() 
    { 
     killMe = true; 
    } 
} 

これが唯一の起動からそれを防ぐことができますが、あなたは時折killMeをチェックして、救済可能性があります。あなたが(何らかのバックグラウンドスレッドのような)実行可能ファイルをループしている場合、次のように言うことができます:

while(!killMe) { 
    /* do work */ 
} 
+0

あなたの迅速な答えに感謝します! しかし、私はすべてのメッセージと私のUIHandlerのコールバックを殺すしたくない... それは私がmyUIHandler.removeCallbacks(longTouchRunnable)を使用した理由です。 特定の対象となるRunnableについて。 期待どおりに機能しないのはなぜですか? – AndroDev

+0

@AndroDev私は答えを編集しました:) – tamtom

+0

PER-FECT! アドバイスに従って問題を解決する方法を見つけました。ありがとうございます! 注:MyRunnableでkillRunnable()を呼び出す必要があり、ハンドラに注意してください。 – AndroDev

関連する問題