답변:
내 경험상 이것을 호출하면 훌륭하게 작동했습니다!
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);
클래스 범위에서 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);
작업 할 수 있습니다.
그런데 왜?
소스 코드를 살펴보면 더 명확하게 이해할 수 있습니다. 핸들러 (MessageQueue)에서 콜백 / 메시지를 제거하는 방법에는 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;
}
}
}