itsource

핸들러에서 모든 콜백을 삭제하려면 어떻게 해야 합니까?

mycopycode 2022. 11. 15. 21:41
반응형

핸들러에서 모든 콜백을 삭제하려면 어떻게 해야 합니까?

기본 활동에서 호출한 하위 활동에서 처리기가 있습니다.이 핸들러는 일부 Runnables의 하위 클래스에서 사용되며 관리할 수 없습니다.자, 이제.onStop이벤트, 액티비티를 완료하기 전에 삭제해야 합니다(어떤 식으로든 전화드렸습니다).finish(), 그러나 계속 호출됩니다).핸들러에서 모든 콜백을 삭제할 수 있는 방법이 있습니까?

내 경험상 이 전화는 훌륭했어!

handler.removeCallbacksAndMessages(null);

remove Callbacks 문서그리고 메세지에는...

obj가 토큰인 콜백 및 전송된 메시지의 보류 중인 게시물을 모두 삭제합니다.토큰이 인 경우 모든 콜백 및 메시지가 삭제됩니다.

특정의 경우Runnable인스턴스, 콜Handler.removeCallbacks(). 이 명령어는Runnableinstance 자체에서 어떤 콜백을 등록 해제할지 결정하므로 게시물이 작성될 때마다 새로운 인스턴스를 작성할 경우 정확한 콜백에 대한 참조가 있는지 확인해야 합니다.Runnable취소해 주세요.예:

Handler myHandler = new Handler();
Runnable myRunnable = new Runnable() {
    public void run() {
        //Some interesting task
    }
};

전화하시면 됩니다.myHandler.postDelayed(myRunnable, x)코드의 다른 위치에 있는 메시지큐에 다른 콜백을 투고하고 보류 중인 콜백을 모두 삭제합니다.myHandler.removeCallbacks(myRunnable)

유감스럽게도 단순히 전체 데이터를 '클리어'할 수는 없습니다.MessageQueue잠깐 동안Handler를 요구해도MessageQueue아이템 추가 및 삭제 방법은 패키지로 보호되기 때문에 오브젝트와 관련되어 있습니다(Android.os 패키지 내의 클래스만 오브젝트를 호출할 수 있습니다).Thin을 작성해야 할 수 있습니다.Handler목록을 관리하는 서브클래스Runnable투고/투고할 때... 또는 메시지 전달을 위한 다른 패러다임을 검토한다.Activity

도움이 되길 바랍니다!

새 핸들러를 정의하고 실행 가능:

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);

Runnable 참조가 없는 경우 첫 번째 콜백에서 메시지의 obj를 가져와 removeCallbacks를 사용합니다.And Messages(): 관련된 모든 콜백을 삭제합니다.

주의해 주십시오.Handler및 aRunnable한 번 작성하도록 합니다.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(..)method, never stopdoIt()메서드 콜을 호출합니다.왜냐하면 그때마다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)정상적으로 동작합니다.

핵심 문장은 '사용하는 항목 또는 사용하는 항목에서 글로벌하게 정의'입니다.

~로josh527라고 말했다.handler.removeCallbacksAndMessages(null);동작할 수 있습니다.
지만만 왜???
소스코드를 보면 좀 더 명확하게 알 수 있어요.핸들러에서 콜백/메시지를 삭제하는 방법에는 다음 3가지가 있습니다(MessageQueue).

  1. 콜백(및 토큰)에 의한 삭제
  2. 메시지로 제거하다무엇(및 토큰)
  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;
        }
    }
}

언급URL : https://stackoverflow.com/questions/5883635/how-to-remove-all-callbacks-from-a-handler

반응형