হ্যান্ডলার থেকে সমস্ত কলব্যাক কীভাবে সরিয়ে নেওয়া যায়?


222

আমার সাব-অ্যাক্টিভিটি থেকে আমার একটি হ্যান্ডলার রয়েছে যা মূল ক্রিয়াকলাপ বলে । এই হ্যান্ডলারটি postDelayকিছু রান্নেবলের কাছে উপ-শ্রেণীর দ্বারা ব্যবহৃত হয় এবং আমি সেগুলি পরিচালনা করতে পারি না। এখন, onStopইভেন্টে, ক্রিয়াকলাপ শেষ করার আগে আমার এগুলি সরিয়ে ফেলা দরকার (কোনওভাবে আমি finish()কল করেছি, তবে এটি এখনও বার বার কল করে)। কোনও হ্যান্ডলার থেকে সমস্ত কলব্যাক সরানোর উপায় আছে কি?

উত্তর:


521

আমার অভিজ্ঞতা এই দুর্দান্ত কাজ!

handler.removeCallbacksAndMessages(null);

ক্যালব্যাকসঅ্যান্ডম্যাসেজগুলি সরানোর জন্য দস্তাবেজে এটি বলে ...

কলব্যাক এবং প্রেরিত বার্তাগুলির কোনও মুলতুবি পোস্ট মুছে ফেলুন যার উদ্দেশ্য টোকেন। যদি টোকেন হয় null, সমস্ত কলব্যাক এবং বার্তা মুছে ফেলা হবে।


2
@ মালাচিয়াজ আমার মনে হয় যে ক্রিয়াকলাপটি ফোকাস হারিয়ে ফেলার পরে কোনও বার্তা হ্যান্ডল করা হচ্ছে না তা নিশ্চিত করার জন্য আমি এটি অনটপ বা অনপেজ এ ব্যবহার করব। কলব্যাক / বার্তা চালিত হওয়ার পরে কী করা দরকার তার উপর নির্ভর করে
বয়

1
আমি বিশ্বাস করি যে এটি করার সময় আমি কিছু ফোনে এনপিই এর আগে দেখেছি তবে এটি কিছুক্ষণ হয়ে গেছে।
ম্যাট ওল্ফ

3
আমার কিছু সমস্যা ছিল removeCallbacksAndMessages(null)আমার কিছু কলব্যাকগুলি সরিয়ে দেবে না। যখন আমি handler.removeCallbacksAndMessages(null)কলব্যাকগুলি গ্রহণ বন্ধ করতে চাই, আমি কল করে আমার হ্যান্ডলারটি বাতিল করতে চাই , তবে যেহেতু আমি কলব্যাকটি পাব, তখন আমি যখন এনপিইর সাথে লুপ করতে চাই তখন আমি একটি এনপিইর মুখোমুখি হব handler.postDelayed()
স্নিকার

@ স্নেকার আপনি কি এখনও নিজের সমস্যার সমাধান করেছেন? নাল সেট করে কলব্যাক এবং বার্তাগুলি সরিয়ে দেওয়ার পরেও হ্যান্ডলারের কলব্যাক কল করা হচ্ছে সেখানে আমার একই সমস্যা রয়েছে।
শ্রিম্পক্র্যাকার্স

1
@ শ্রিম্পক্র্যাকার্স আমি আপনার চলমানযোগ্য উদাহরণ রেখেছি এবং ব্যবহার yourHandler.removeCallbacks(yourRunnable)করা সবচেয়ে নির্ভরযোগ্য ছিল। আজও তা ব্যবহার করছি।
স্নিকার

19

যে কোনও নির্দিষ্ট 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)

দুর্ভাগ্যবশত, আপনি না কেবল সমগ্র "Clear 'পারি MessageQueueএকটি জন্য Handler, এমনকি যদি আপনার জন্য একটি অনুরোধ করতে MessageQueueএর সাথে জড়িত কারণ যুক্ত করা এবং আইটেম সরানোর জন্য পদ্ধতি প্যাকেজ সংরক্ষিত (শুধুমাত্র android.os প্যাকেজ মধ্যে ক্লাস তাদের কল করতে পারেন) হয় অবজেক্ট। সেগুলির Handlerতালিকা Runnableপোস্ট করা / চালিত হওয়ার সাথে সাথে পরিচালনা করার জন্য আপনার একটি পাতলা সাবক্লাস তৈরি করতে হতে পারে ... অথবা প্রত্যেকের মধ্যে আপনার বার্তা প্রেরণের জন্য অন্য একটি দৃষ্টান্তটি দেখুনActivity

আশা করি এইটি কাজ করবে!


ধন্যবাদ, আমি জানি। তবে অনেকগুলি সাব-ক্লাসে আমার প্রচুর রান্নেবল রয়েছে, এবং সেগুলি পরিচালনা করা একটি মহাকাব্য কাজ! অনসটপ () ইভেন্টে সেগুলি সরিয়ে দেওয়ার কি কোনও উপায় আছে?
লুক ভো

বুঝেছি, আমি উত্তরটি আরও কিছু তথ্য দিয়ে আপডেট করেছি। সংক্ষিপ্ত সংস্করণ হ্যান্ডলারের বার্তার
সারিটি


6

একটি নতুন হ্যান্ডলার এবং চলমানযোগ্য সংজ্ঞা দিন:

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

3

অনুগ্রহ করে নোট করুন যে কারও 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আপনি কী ব্যবহার করেন সেগুলিকে বৈশ্বিক হিসাবে সংজ্ঞায়িত করুন '


1

যেমন josh527বলা হয়েছে, handler.removeCallbacksAndMessages(null);কাজ করতে পারে।
কিন্তু কেন?
যদি আপনার উত্স কোডটি একবার দেখে থাকে তবে আপনি এটি আরও স্পষ্টভাবে বুঝতে পারবেন। হ্যান্ডলার (মেসেজকিউ) থেকে কলব্যাক / বার্তাগুলি সরানোর জন্য 3 ধরণের পদ্ধতি রয়েছে:

  1. কলব্যাক (এবং টোকেন) দ্বারা সরান
  2. বার্তা দ্বারা সরান what কি (এবং টোকেন)
  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);
}

মেসেজকিউ.জভা আসল কাজটি করুন:

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;
        }
    }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.