メイン Activity によって呼び出されたサブアクティビティから Handler があります。このハンドラーは、サブクラスによって postDelay
Runnableの一部として使用され、それらを管理できません。さて、onStop
イベントで、アクティビティを完了する前にそれらを削除する必要があります(どういうわけかfinish()
を呼び出しましたが、それでも何度も呼び出します)。ハンドラーからすべてのコールバックを削除する方法はありますか?
私の経験では、これを呼び出すことはうまくいきました!
handler.removeCallbacksAndMessages(null);
RemoveCallbacksAndMessagesのドキュメントには、次のように書かれています...
Objがトークンであるコールバックおよび送信済みメッセージの保留中の投稿を削除します。 トークンが
null
の場合、すべてのコールバックとメッセージが削除されます。
特定のRunnable
name__インスタンスについては、Handler.removeCallbacks()
を呼び出します。 Runnable
name__インスタンス自体を使用して登録解除するコールバックを決定するため、投稿が作成されるたびに新しいインスタンスを作成する場合は、キャンセルするために正確なRunnable
name__への参照があることを確認する必要があります。例:
Handler myHandler = new Handler();
Runnable myRunnable = new Runnable() {
public void run() {
//Some interesting task
}
};
myHandler.postDelayed(myRunnable, x)
を呼び出して、コード内の他の場所のメッセージキューに別のコールバックを投稿し、myHandler.removeCallbacks(myRunnable)
を使用して保留中のコールバックをすべて削除できます。
残念ながら、MessageQueue
name__のHandler
name__オブジェクトをリクエストしても、アイテムを追加および削除するメソッドはパッケージで保護されているため、MessageQueue
name__全体を単純に「クリア」することはできません(Android.osパッケージ内のクラスのみが呼び出すことができます)それら)。薄いHandler
name__サブクラスを作成して、Runnable
name__sのリストを管理する必要があります。または、各Activity
name__間でメッセージを渡すための別のパラダイムを見てください
お役に立てば幸いです!
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);
実際、ここには少し重要なポイントがあります。 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
インスタンスを作成するためです。このようにして、handlerおよび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;
}
}
}