回答:
私の経験では、これを呼び出すのはうまくいきました!
handler.removeCallbacksAndMessages(null);
removeCallbacksAndMessagesのドキュメントでは、それは言う...
objがトークンであるコールバックと送信メッセージの保留中の投稿をすべて削除します。トークンがの場合
null
、すべてのコールバックとメッセージが削除されます。
removeCallbacksAndMessages(null)
一部のコールバックを削除できないという問題がありました。コールバックの受信を停止する場合は、呼び出しhandler.removeCallbacksAndMessages(null)
てハンドラーをnullに設定しますが、それでもコールバックを取得するため、でループするときにNPEが発生しますhandler.postDelayed()
。
yourHandler.removeCallbacks(yourRunnable)
が最も信頼できることがわかりました。今日もそれを使用しています。
特定のRunnable
インスタンスについては、を呼び出しますHandler.removeCallbacks()
。Runnable
登録解除するコールバックを決定するためにインスタンス自体を使用するため、投稿が行われるたびに新しいインスタンスを作成する場合は、Runnable
キャンセルする正確なものへの参照があることを確認する必要があることに注意してください。例:
Handler myHandler = new Handler();
Runnable myRunnable = new Runnable() {
public void run() {
//Some interesting task
}
};
を呼び出しmyHandler.postDelayed(myRunnable, x)
て、コード内の他の場所にあるメッセージキューに別のコールバックをポストし、保留中のすべてのコールバックを削除できます。myHandler.removeCallbacks(myRunnable)
残念ながら、項目に追加および削除するメソッドはパッケージで保護されているため(android.osパッケージ内のクラスのみがそれらを呼び出すことができるため)、関連付けられているオブジェクトをリクエストしても、の全体MessageQueue
を単純に「クリア」することはできません。投稿/実行されたsのリストを管理するために薄いサブクラスを作成する必要があるかもしれません...またはそれぞれの間でメッセージを渡すための別のパラダイムを確認してくださいHandler
MessageQueue
Handler
Runnable
Activity
お役に立てば幸いです。
Runnable参照がない場合は、最初のコールバックでメッセージのobjを取得し、removeCallbacksAndMessages()を使用して関連するすべてのコールバックを削除します。
新しいハンドラーと実行可能ファイルを定義します。
private Handler handler = new Handler(Looper.getMainLooper());
private Runnable runnable = new Runnable() {
@Override
public void run() {
// Do what ever you want
}
};
コールポストの遅延:
handler.postDelayed(runnable, sleep_time);
ハンドラーからコールバックを削除します。
handler.removeCallbacks(runnable);
1つが作成されるように、クラスのスコープ内でHandler
とを定義する必要があることに注意してくださいRunnable
。removeCallbacks(Runnable)
それらを複数回定義しない限り、正しく動作します。理解を深めるために、次の例をご覧ください。
間違った方法:
public class FooActivity extends Activity {
private void handleSomething(){
Handler handler = new Handler();
Runnable runnable = new Runnable() {
@Override
public void run() {
doIt();
}
};
if(shouldIDoIt){
//doIt() works after 3 seconds.
handler.postDelayed(runnable, 3000);
} else {
handler.removeCallbacks(runnable);
}
}
public void onClick(View v){
handleSomething();
}
}
onClick(..)
メソッドを呼び出す場合、doIt()
呼び出す前にメソッドの呼び出しを停止することはありません。たびに作成されるため、new Handler
およびnew Runnable
インスタンス。このようにして、ハンドラーおよび実行可能インスタンスに属する必要な参照を失いました。
正しい方法:
public class FooActivity extends Activity {
Handler handler = new Handler();
Runnable runnable = new Runnable() {
@Override
public void run() {
doIt();
}
};
private void handleSomething(){
if(shouldIDoIt){
//doIt() works after 3 seconds.
handler.postDelayed(runnable, 3000);
} else {
handler.removeCallbacks(runnable);
}
}
public void onClick(View v){
handleSomething();
}
}
このようにして、実際の参照を失うことなく、removeCallbacks(runnable)
正常に動作します。
キーセンテンスは、「あなたActivity
またはFragment
あなたが使うものにおいてそれらをグローバルとして定義すること」です。
josh527
言った、handler.removeCallbacksAndMessages(null);
作業することができます。
しかし、なぜ?
ソースコードを見れば、より明確に理解できます。ハンドラー(メッセージキュー)からコールバック/メッセージを削除するには、3種類のメソッドがあります。
Handler.java(いくつかのオーバーロードメソッドを残す)
/**
* Remove any pending posts of Runnable <var>r</var> with Object
* <var>token</var> that are in the message queue. If <var>token</var> is null,
* all callbacks will be removed.
*/
public final void removeCallbacks(Runnable r, Object token)
{
mQueue.removeMessages(this, r, token);
}
/**
* Remove any pending posts of messages with code 'what' and whose obj is
* 'object' that are in the message queue. If <var>object</var> is null,
* all messages will be removed.
*/
public final void removeMessages(int what, Object object) {
mQueue.removeMessages(this, what, object);
}
/**
* Remove any pending posts of callbacks and sent messages whose
* <var>obj</var> is <var>token</var>. If <var>token</var> is null,
* all callbacks and messages will be removed.
*/
public final void removeCallbacksAndMessages(Object token) {
mQueue.removeCallbacksAndMessages(this, token);
}
MessageQueue.javaが実際の作業を行います。
void removeMessages(Handler h, int what, Object object) {
if (h == null) {
return;
}
synchronized (this) {
Message p = mMessages;
// Remove all messages at front.
while (p != null && p.target == h && p.what == what
&& (object == null || p.obj == object)) {
Message n = p.next;
mMessages = n;
p.recycleUnchecked();
p = n;
}
// Remove all messages after front.
while (p != null) {
Message n = p.next;
if (n != null) {
if (n.target == h && n.what == what
&& (object == null || n.obj == object)) {
Message nn = n.next;
n.recycleUnchecked();
p.next = nn;
continue;
}
}
p = n;
}
}
}
void removeMessages(Handler h, Runnable r, Object object) {
if (h == null || r == null) {
return;
}
synchronized (this) {
Message p = mMessages;
// Remove all messages at front.
while (p != null && p.target == h && p.callback == r
&& (object == null || p.obj == object)) {
Message n = p.next;
mMessages = n;
p.recycleUnchecked();
p = n;
}
// Remove all messages after front.
while (p != null) {
Message n = p.next;
if (n != null) {
if (n.target == h && n.callback == r
&& (object == null || n.obj == object)) {
Message nn = n.next;
n.recycleUnchecked();
p.next = nn;
continue;
}
}
p = n;
}
}
}
void removeCallbacksAndMessages(Handler h, Object object) {
if (h == null) {
return;
}
synchronized (this) {
Message p = mMessages;
// Remove all messages at front.
while (p != null && p.target == h
&& (object == null || p.obj == object)) {
Message n = p.next;
mMessages = n;
p.recycleUnchecked();
p = n;
}
// Remove all messages after front.
while (p != null) {
Message n = p.next;
if (n != null) {
if (n.target == h && (object == null || n.obj == object)) {
Message nn = n.next;
n.recycleUnchecked();
p.next = nn;
continue;
}
}
p = n;
}
}
}