40

メソッドから呼び出しています:

myHandler.postDelayed(mMyRunnableHide, 6000);

これは次を呼び出します:

public Runnable mMyRunnableHide = new Runnable()
{

    public void run()
    {
        mTextDisplay.setText("");
        DisplayX();
    }
 };

画面上のボタンがクリックされた場合、ランナブルを停止したい:

   Button next = (Button) findViewById(R.id.Breaction);
    next.setOnClickListener(new View.OnClickListener() {
        public void onClick(View view) {

            myHandler.removeCallbacks(mMyRunnableHide);

            mTextDisplay.setText("");
            DisplayX();
            }
        });   
    }

removecallbacks はランナブルを停止していません。私は何を間違っていますか?正しい方法を使用していますか? ユーザーがボタンをクリックしたときに、ランナブルを「実行しない」にしたいだけです。

助けてくれてありがとう。

4

5 に答える 5

36

保留中のメッセージ(Runnables)removeCallbacks(..)のみを停止するように見えます。ランナブルがすでに開始されている場合、それを停止することはできません (少なくともこの方法では)。

または、Runnable クラスを拡張して、次のようなキル スイッチを与えることもできます。

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

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

      /* do your work */
   }

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

これは起動を妨げるだけですが、時々チェックkillMeして救済することができます. ランナブルをループしている場合 (ある種のバックグラウンド スレッドなど)、次のように言うことができます。

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

お役に立てれば

編集これに関する最新情報を投稿したかっただけです。この最初の投稿以降、Google は、これらすべてを処理する AsyncTask という優れたクラスを考案しました。これを読んでいる人は、これが正しい方法であるため、実際に調べる必要があります。

ここでそれについて読むことができます

于 2011-04-30T20:29:34.570 に答える
14

Handler.removeCallbackは同期的であり、次の条件を満たしていればうまく動作します:

  1. postDelayed常にメインスレッドで呼び出します。
  2. removeCallbackあなたは常にメインスレッドで呼び出します
  3. postDelayedコールバックを削除した後、再度呼び出すことはありません。

あなたの場合removeCallbacks、メインスレッドで実行されるボタンハンドラーから呼び出されます。しかし、コード内で を呼び出す場所を示していませんでしたpostDelayed。バックグラウンドスレッドから呼び出すと、問題が発生します。

これらのメソッドをバックグラウンド スレッドから呼び出しておらず、呼び出しの順序が正しい場合は、構成の変更 (画面の回転など) でのアクティビティの再作成により、キャンセルされていないタスクが不注意に生きたままになっている可能性があります。この種の問題を防ぐため に、必ずメソッドremoveCallbacks内で再度呼び出すようにしてください。onDestroy

于 2016-03-15T16:04:25.380 に答える
7

mtmurdock が説明していることを達成する別の方法を次に示します。このクラスでは、Runnable が匿名の内部クラスとして定義されている任意のクラスでインスタンス変数を編集できます。

package support;

/**
* Runnable that can be stopped from executing
*/
public abstract class KillableRunnable implements Runnable{

private boolean isKilled=false;

/**
 * Instead of Overriding run(), override this method to perform a Runnable operation. 
 * This will allow editing instance variables in the class that this Runnable is defined
 */
public abstract void doWork();

//The handler that posts this Runnable will call this method. 
//By default, check if it has been killed. doWork() will now be the method 
//override to implement this Runnable
@Override
final public void run(){
    if(!isKilled){
        doWork();
    }
}

final public void kill(){
    isKilled=true;
}
}
于 2015-02-20T17:54:06.503 に答える