थ्रेड के अंदर हैंडलर नहीं बना सकते हैं जिसे Looper.prepare () नहीं कहा जाता है


981

निम्नलिखित अपवाद का मतलब क्या है; मेरे द्वारा यह कैसे किया जा सकता है?

यह कोड है:

Toast toast = Toast.makeText(mContext, "Something", Toast.LENGTH_SHORT);

यह अपवाद है:

java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
     at android.os.Handler.<init>(Handler.java:121)
     at android.widget.Toast.<init>(Toast.java:68)
     at android.widget.Toast.makeText(Toast.java:231)

8
इस पुस्तकालय की जाँच करें compile 'com.shamanland:xdroid-toaster:0.0.5', इसकी आवश्यकता नहीं है runOnUiThread()या Contextपरिवर्तनशील नहीं है , सभी दिनचर्या समाप्त हो गई है! Toaster.toast(R.string.my_msg);यहाँ केवल उदाहरण है: github.com/shamanland/xdroid-toaster-example
Oleksii K.

120
क्या एक बेवकूफ त्रुटि संदेश! यह उतना ही सरल हो सकता था - गैर-यूआई थ्रेड से इसे कॉल नहीं किया जा सकता है जब किसी गैर-यूआई थ्रेड से दृश्य स्पर्श किए जाते हैं।
धीरज भास्कर

11
उन लोगों के लिए जो अलग-अलग कोड से एक ही अपवाद संदेश प्राप्त करते हैं: अपवाद संदेश का मतलब यह है कि आप उस कोड को थ्रेड के माध्यम से कॉल कर रहे हैं, जिसने कोई अन्नदाता तैयार नहीं किया है। आम तौर पर इसका मतलब है कि आप यूआई थ्रेड से कॉल नहीं कर रहे हैं लेकिन आपको (ओपी के मामले में) - एक सामान्य थ्रेड लूपर तैयार नहीं करता है, लेकिन यूआई थ्रेड हमेशा करते हैं।
हेलिन वांग

@OleksiiKropachov आपके द्वारा उल्लिखित पुस्तकालय का कार्यान्वयन एक runOnUiThread () करने के समान है।
हेलिन वैंग

हां, लेकिन यह एक बहुत उपयोगी आवरण है
ओलेक्सी के।

जवाबों:


696

आप इसे वर्कर थ्रेड से बुला रहे हैं। आपको कॉल करने की आवश्यकता हैToast.makeText() मुख्य थ्रेड के भीतर (UI से निपटने वाले अन्य कार्यों । आप एक हैंडलर का उपयोग कर सकते हैं, उदाहरण के लिए।

देखो यूआई थ्रेड के साथ संचार दस्तावेज में। संक्षेप में:

// Set this up in the UI thread.

mHandler = new Handler(Looper.getMainLooper()) {
    @Override
    public void handleMessage(Message message) {
        // This is where you do your work in the UI thread.
        // Your worker tells you in the message what to do.
    }
};

void workerThread() {
    // And this is how you call it from the worker thread:
    Message message = mHandler.obtainMessage(command, parameter);
    message.sendToTarget();
}

अन्य विकल्प:

आप एक AsyncTask का उपयोग कर सकते हैं , जो पृष्ठभूमि में चलने वाली अधिकांश चीजों के लिए अच्छी तरह से काम करता है। इसमें हुक हैं जो आप प्रगति को इंगित करने के लिए कॉल कर सकते हैं, और जब यह किया जाता है।

आप Activ.runOnUiThread () का भी उपयोग कर सकते हैं ।


मूल समस्या के बारे में क्या (यह AlertDialog के बारे में नहीं था)?
इवान जी।

5
बस मेरे दो सेंट को जोड़कर कैली ने क्या कहा। यह एक संक्षिप्त प्रदर्शन प्रदान करने के लिए बेहतर होगा कि आप क्या मतलब है (हालांकि विवादित), क्योंकि एक कोडित उदाहरण अक्सर खुद के लिए वॉल्यूम बोल सकता है।
cdata

5
पूर्ण तकनीकी उत्तर के लिए इस prasanta-paul.blogspot.kr/2013/09/…
tony9099

3
लगभग सभी प्रोग्रामिंग भाषाओं में AFAIK जो GUI का समर्थन करती है, यदि आप सीधे GUI के साथ / बदल / प्रदर्शन / बातचीत करते हैं, तो इसे प्रोग्राम के मुख्य धागे पर किया जाना चाहिए।
अहमद

(and most other functions dealing with the UI)पृष्ठभूमि से प्रयोग करने योग्य UI फ़ंक्शन का एक उदाहरण है android.support.design.widget.Snackbar- UI थ्रेड से कॉल न करने पर इसकी कार्यक्षमता कम हो जाती है।
स्क्रूफी

852

आपको Toast.makeText(...)UI थ्रेड से कॉल करने की आवश्यकता है :

activity.runOnUiThread(new Runnable() {
  public void run() {
    Toast.makeText(activity, "Hello", Toast.LENGTH_SHORT).show();
  }
});

यह दूसरे (डुप्लिकेट) एसओ उत्तर से कॉपी-पेस्ट किया जाता है ।


13
बहुत बढ़िया जवाब। इससे मुझे थोड़ी देर के लिए भ्रम हो गया था। बस ध्यान दें, मुझे गतिविधि की आवश्यकता नहीं थी। runOnUiThread से पहले।
सेन92

448

अद्यतन - 2016

सबसे अच्छा विकल्प का उपयोग करने के लिए है RxAndroid(के लिए विशिष्ट बाइंडिंग RxJavaके लिए) Pमें MVPप्रभारी डेटा के लिए लेने के लिए।

Observableअपने मौजूदा तरीके से लौटकर शुरू करें ।

private Observable<PojoObject> getObservableItems() {
    return Observable.create(subscriber -> {

        for (PojoObject pojoObject: pojoObjects) {
            subscriber.onNext(pojoObject);
        }
        subscriber.onCompleted();
    });
}

इस तरह इस अवलोकन का उपयोग करें -

getObservableItems().
subscribeOn(Schedulers.io()).
observeOn(AndroidSchedulers.mainThread()).
subscribe(new Observer<PojoObject> () {
    @Override
    public void onCompleted() {
        // Print Toast on completion
    }

    @Override
    public void onError(Throwable e) {}

    @Override
    public void onNext(PojoObject pojoObject) {
        // Show Progress
    }
});
}

-------------------------------------------------- -------------------------------------------------- ------------------------------

मुझे पता है कि मुझे थोड़ी देर हो गई है लेकिन यहां जाता हूं। एंड्रॉइड मूल रूप से दो थ्रेड प्रकारों पर कार्य करता है जैसे UI थ्रेड और बैकग्राउंड थ्रेड । Android प्रलेखन के अनुसार -

इस समस्या को ठीक करने के लिए UI थ्रेड के बाहर से एंड्रॉइड यूआई टूलकिट का उपयोग न करें, एंड्रॉइड यूआई थ्रेड को अन्य थ्रेड्स से एक्सेस करने के कई तरीके प्रदान करता है। यहां उन तरीकों की सूची दी गई है जो मदद कर सकते हैं:

Activity.runOnUiThread(Runnable)  
View.post(Runnable)  
View.postDelayed(Runnable, long)

अब इस समस्या को हल करने के लिए विभिन्न तरीके हैं।

मैं इसे कोड नमूने द्वारा समझाऊंगा:

runOnUiThread

new Thread()
{
    public void run()
    {
        myactivity.this.runOnUiThread(new Runnable()
        {
            public void run()
            {
                //Do your UI operations like dialog opening or Toast here
            }
        });
    }
}.start();

Looper

क्लास एक थ्रेड के लिए एक संदेश लूप चलाने के लिए उपयोग किया जाता है। डिफ़ॉल्ट रूप से थ्रेड्स में एक संदेश लूप नहीं होता है जो उनके साथ जुड़ा हुआ है; एक बनाने के लिए, कॉल तैयारी () थ्रेड में जो लूप को चलाने के लिए है, और फिर लूप () लूप बंद होने तक संदेशों को संसाधित करने के लिए।

class LooperThread extends Thread {
    public Handler mHandler;

    public void run() {
        Looper.prepare();

        mHandler = new Handler() {
            public void handleMessage(Message msg) {
                // process incoming messages here
            }
        };

        Looper.loop();
    }
}

AsyncTask

AsyncTask आपको अपने यूजर इंटरफेस पर अतुल्यकालिक कार्य करने की अनुमति देता है। यह वर्कर थ्रेड में ब्लॉकिंग ऑपरेशंस करता है और फिर यूआई थ्रेड पर रिजल्ट प्रकाशित करता है, बिना आपको थ्रेड और / या हैंडलर को संभालने की आवश्यकता होती है।

public void onClick(View v) {
    new CustomTask().execute((Void[])null);
}


private class CustomTask extends AsyncTask<Void, Void, Void> {

    protected Void doInBackground(Void... param) {
        //Do some work
        return null;
    }

    protected void onPostExecute(Void param) {
        //Print Toast or open dialog
    }
}

हैंडलर

एक हैंडलर आपको थ्रेड के MessageQueue से जुड़े संदेश और Runnable ऑब्जेक्ट को भेजने और संसाधित करने की अनुमति देता है।

Message msg = new Message();


new Thread()
{
    public void run()
    {
        msg.arg1=1;
        handler.sendMessage(msg);
    }
}.start();



Handler handler = new Handler(new Handler.Callback() {

    @Override
    public boolean handleMessage(Message msg) {
        if(msg.arg1==1)
        {
            //Print Toast or open dialog        
        }
        return false;
    }
});

7
यह वही है जिसकी मुझे तलाश थी। विशेष रूप से पहला उदाहरणrunOnUiThread
नवीन

5
धन्यवाद, एंड्रॉइड प्रोग्रामिंग के 5 साल और मुझे कभी नहीं पता था कि Viewविधियां भी हैं post(Runnable)और postDelayed(Runnable, long)! इतने सारे हैंडलर व्यर्थ। :)
फेनिक्स वोल्टेरेस

उन लोगों के लिए जो हैंडलर के उदाहरण से भ्रमित हैं: वह कौन सा धागा है जो "नया हैंडलर (कॉलबैक)" के लिए बाध्य है? यह उस थ्रेड के लिए बाध्य है जिसने हैंडलर बनाया है।
हेलिन वैंग

1
यह सबसे अच्छा विकल्प क्यों है ?
इगोरगानापोलस्की

मैं usInBackground करता हूं और मैं एक ArrayList वापस लेना चाहता हूं, लेकिन मुझे हमेशा यह त्रुटि मिलती है: जो धागे के अंदर हैंडलर नहीं बना सकता है उसने Looper.prepare () नहीं कहा है। देखिये यह मेरा सवाल है stackoverflow.com/questions/45562615/… लेकिन मुझे यहाँ इस उत्तर से समाधान नहीं मिल सकता है
WeSt

120

Toast.makeText()केवल मेन / यूआई थ्रेड से बुलाया जाना चाहिए। Looper.getMainLooper () आपको इसे प्राप्त करने में मदद करता है:

new Handler(Looper.getMainLooper()).post(new Runnable() {
    @Override
    public void run() {
        Toast toast = Toast.makeText(mContext, "Something", Toast.LENGTH_SHORT);
    }
});

इस पद्धति का एक फायदा यह है कि आप इसे गतिविधि या संदर्भ के बिना उपयोग कर सकते हैं।


2
धन्यवाद अन्य उत्तर मेरे लिए काम कर रहे थे। मैं दृढ़ता का प्रबंधन करने के लिए एक पुस्तकालय चीनी रिकॉर्ड का उपयोग कर रहा हूं। और इसके अंदर मेरे पास गतिविधि नहीं है। लेकिन यह आश्चर्यजनक रूप से काम करता है
cabaji99

91

जब आप हैंडलर से पहले लूपर तैयार नहीं होने के कारण रनटाइम एक्ससेप्शन देखते हैं, तो यह कोशिश करें।

Handler handler = new Handler(Looper.getMainLooper()); 

handler.postDelayed(new Runnable() {
  @Override
  public void run() {
  // Run your task here
  }
}, 1000 );

हैंडलर एक अमूर्त वर्ग है। यह संकलन नहीं करता है
चुपके रब्बी

2
@StealthRabbi ने सही नामस्थान से हैंडलर का आयात कियाandroid.os.Handler
नाइट फेयर

यह मुद्दा नहीं हो सकता है। एक लूपर कॉलिंग क्लास, अवधि से मौजूद नहीं हो सकता है।
इगोरगानापोलस्की

42

मैं उसी समस्या में भाग गया, और यहाँ है कि मैंने इसे कैसे तय किया:

private final class UIHandler extends Handler
{
    public static final int DISPLAY_UI_TOAST = 0;
    public static final int DISPLAY_UI_DIALOG = 1;

    public UIHandler(Looper looper)
    {
        super(looper);
    }

    @Override
    public void handleMessage(Message msg)
    {
        switch(msg.what)
        {
        case UIHandler.DISPLAY_UI_TOAST:
        {
            Context context = getApplicationContext();
            Toast t = Toast.makeText(context, (String)msg.obj, Toast.LENGTH_LONG);
            t.show();
        }
        case UIHandler.DISPLAY_UI_DIALOG:
            //TBD
        default:
            break;
        }
    }
}

protected void handleUIRequest(String message)
{
    Message msg = uiHandler.obtainMessage(UIHandler.DISPLAY_UI_TOAST);
    msg.obj = message;
    uiHandler.sendMessage(msg);
}

UIHandler बनाने के लिए, आपको निम्नलिखित कार्य करने होंगे:

    HandlerThread uiThread = new HandlerThread("UIHandler");
    uiThread.start();
    uiHandler = new UIHandler((HandlerThread) uiThread.getLooper());

उम्मीद है की यह मदद करेगा।


मैंने आपके कोड का उपयोग करने की कोशिश की, लेकिन मैं हार गया और यह सुनिश्चित नहीं कर पाया कि onCreate methodमेरी स्थिति में AsyncTask से कॉल या कॉल कैसे करें, क्या आप यह जानने के लिए पूरी कोड पोस्ट करेंगे कि कैसे चीजें काम करती हैं?
निक कान

2
क्या वह अंतिम पंक्ति नहीं पढ़ी जानी चाहिए uiHandler = new UIHandler(uiThread.getLooper()); ?
बीर मी।

36

त्रुटि का कारण:

वर्कर थ्रेड्स बैकग्राउंड टास्क करने के लिए होते हैं और आप यूआई पर वर्कर थ्रेड के अंदर कुछ भी नहीं दिखा सकते हैं जब तक कि आप रनऑन यूट्रेड की तरह कॉल न करें । अगर आप runOnUiThread पर कॉल किए बिना UI थ्रेड पर कुछ भी दिखाने की कोशिश करते हैं, तो एक होगा java.lang.RuntimeException

इसलिए, यदि आप वर्कर थ्रेड से activityकॉल कर रहे हैं Toast.makeText(), तो यह करें:

runOnUiThread(new Runnable() 
{
   public void run() 
   {
      Toast toast = Toast.makeText(getApplicationContext(), "Something", Toast.LENGTH_SHORT).show();    
   }
}); 

उपरोक्त कोड यह सुनिश्चित करता है कि आप टोस्ट संदेश दिखा रहे हैं UI threadक्योंकि आप इसे runOnUiThreadविधि के अंदर बुला रहे हैं । तो अब और नहीं java.lang.RuntimeException


23

वही मैंने किया।

new Handler(Looper.getMainLooper()).post(new Runnable() {
    @Override
    public void run() {
        Toast(...);
    }
});

दृश्य घटक बाहरी थ्रेड्स से परिवर्तन के लिए "लॉक" होते हैं। इसलिए, चूंकि टोस्ट मुख्य स्क्रीन पर सामान दिखाता है जिसे मुख्य धागे द्वारा प्रबंधित किया जाता है, आपको उस धागे पर इस कोड को चलाने की आवश्यकता है। उम्मीद है की वो मदद करदे:)


मैंने यही तरीका इस्तेमाल किया। हालाँकि, क्या यह लीक की संभावना को छोड़ देता है, क्योंकि रननेबल का अनाम आंतरिक वर्ग गतिविधि का एक निहित संदर्भ रखेगा?
पीटर जी। विलियम्स

1
यह एक ठीक बात है :) बस सुरक्षित पक्ष पर होने के लिए getApplicationContext () या ऐसा कुछ का उपयोग करें।
आखिरकार

22

मुझे यह त्रुटि तब तक हो रही थी जब तक मैंने निम्नलिखित नहीं किया।

public void somethingHappened(final Context context)
{
    Handler handler = new Handler(Looper.getMainLooper());
    handler.post(
        new Runnable()
        {
            @Override
            public void run()
            {
                Toast.makeText(context, "Something happened.", Toast.LENGTH_SHORT).show();
            }
        }
    );
}

और इसे एक एकल वर्ग में बनाया:

public enum Toaster {
    INSTANCE;

    private final Handler handler = new Handler(Looper.getMainLooper());

    public void postMessage(final String message) {
        handler.post(
            new Runnable() {
                @Override
                public void run() {
                    Toast.makeText(ApplicationHolder.INSTANCE.getCustomApplication(), message, Toast.LENGTH_SHORT)
                        .show();
                }
            }
        );
    }

}

आप टोस्टर का उपयोग कहां कर रहे हैं ? आपके पहले स्निपेट में इसका इस्तेमाल नहीं किया गया है ...
इगोरगानापोलस्की

1
यह एक सुविधा वर्ग था जिसका मैं उपयोग करता था Toaster.INSTANCE.postMessage(ResourceUtils.getString(R.string.blah));(लंबा मुझे पता है! हमने इसे बाद में कम कर दिया), हालांकि मैं थोड़ी देर में टोस्ट का उपयोग नहीं कर रहा हूं
EpicPandaForce

तो क्या ApplicationHolder.INSTANCEमूल्यांकन करता है?
इगोरगानापोलस्की

इस प्रक्रिया के मौजूद होने पर, आवेदन पर विचार करते हुए CustomApplicationसेट का एक स्थिर वैरिएबल CustomApplication.onCreate()हमेशा मौजूद रहता है, इस संदर्भ का उपयोग विश्व स्तर पर किया जा सकता है
EpicPandaForce

11
 runOnUiThread(new Runnable() {
            public void run() {
                Toast.makeText(mContext, "Message", Toast.LENGTH_SHORT).show();
            }
        });

2
यह मेरे लिए काम करता है और मैं runOnUiThread(() -> { Toast toast = Toast.makeText(getApplicationContext(), "Message", Toast.LENGTH_SHORT); toast.show(); });
बजे


9

ऐसा इसलिए है क्योंकि Toast.makeText () एक श्रमिक थ्रेड से कॉल कर रहा है। इसे इस तरह से मुख्य UI थ्रेड से कॉल किया जाना चाहिए

runOnUiThread(new Runnable() {
      public void run() {
        Toast toast = Toast.makeText(mContext, "Something", Toast.LENGTH_SHORT);
      }
 });

8

ChicoBird द्वारा जवाब मेरे लिए काम किया। मेरे द्वारा किया गया एकमात्र बदलाव UIHandler के निर्माण में था जहाँ मुझे करना था

HandlerThread uiThread = new HandlerThread("UIHandler");

ग्रहण ने कुछ और स्वीकार करने से इनकार कर दिया। समझ में आता है कि मुझे लगता है।

इसके अलावा uiHandlerस्पष्ट रूप से एक वर्ग वैश्विक कहीं परिभाषित है। मैं अभी भी यह समझने का दावा नहीं करता कि एंड्रॉइड यह कैसे कर रहा है और क्या चल रहा है, लेकिन मुझे खुशी है कि यह काम करता है। अब मैं इसका अध्ययन करने के लिए आगे बढ़ूंगा और देखूंगा कि क्या मैं समझ सकता हूं कि एंड्रॉइड क्या कर रहा है और क्यों इन सभी हुप्स और लूप से गुजरना पड़ता है। ChicoBird मदद के लिए धन्यवाद।


6

पहला कॉल Looper.prepare()और फिर Toast.makeText().show()अंतिम कॉल Looper.loop()जैसे:

Looper.prepare() // to be able to make toast
Toast.makeText(context, "not connected", Toast.LENGTH_LONG).show()
Looper.loop()

यह उत्तर क्यों दिया गया है?
DkPathak 10

5

Rxjava और RxAndroid उपयोगकर्ता के लिए:

public static void shortToast(String msg) {
    Observable.just(msg)
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(message -> {
                Toast.makeText(App.getInstance(), message, Toast.LENGTH_SHORT).show();
            });
}

वे कोष्ठक अनावश्यक हैं
बोरजा

4

मैं उसी मुद्दे पर चल रहा था जब मेरे कॉलबैक एक संवाद दिखाने की कोशिश करेंगे।

मैंने गतिविधि में समर्पित विधियों के साथ हल किया - गतिविधि उदाहरण सदस्य स्तर पर - जो कि उपयोग करता हैrunOnUiThread(..)

public void showAuthProgressDialog() {
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            mAuthProgressDialog = DialogUtil.getVisibleProgressDialog(SignInActivity.this, "Loading ...");
        }
    });
}

public void dismissAuthProgressDialog() {
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            if (mAuthProgressDialog == null || ! mAuthProgressDialog.isShowing()) {
                return;
            }
            mAuthProgressDialog.dismiss();
        }
    });
}

2
Handler handler2;  
HandlerThread handlerThread=new HandlerThread("second_thread");
handlerThread.start();
handler2=new Handler(handlerThread.getLooper());

अब मुख्य थ्रेड की तुलना में हैंडलर 2 संदेशों को संभालने के लिए एक अलग थ्रेड का उपयोग करेगा।


1

एक सूत्र में एक संवाद या टोस्टर प्रदर्शित करने के लिए, गतिविधि का उपयोग करने के लिए सबसे संक्षिप्त तरीका है।

उदाहरण के लिए:

new Thread(new Runnable() {
    @Override
    public void run() {
        myActivity.runOnUiThread(new Runnable() {
            public void run() {
                myActivity.this.processingWaitDialog = new ProgressDialog(myActivity.this.getContext());
                myActivity.this.processingWaitDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
                myActivity.this.processingWaitDialog.setMessage("abc");
                myActivity.this.processingWaitDialog.setIndeterminate(true);
                myActivity.this.processingWaitDialog.show();
            }
        });
        expenseClassify.serverPost(
                new AsyncOperationCallback() {
                    public void operationCompleted(Object sender) {
                        myActivity.runOnUiThread(new Runnable() {
                            public void run() {
                                if (myActivity.this.processingWaitDialog != null 
                                        && myActivity.this.processingWaitDialog.isShowing()) {
                                    myActivity.this.processingWaitDialog.dismiss();
                                    myActivity.this.processingWaitDialog = null;
                                }
                            }
                        }); // .runOnUiThread(new Runnable()
...

0

टोस्ट, AlertDialogs को UI थ्रेड पर चलाने की आवश्यकता है, आप Android विकास में उन्हें ठीक से उपयोग करने के लिए Asynctask का उपयोग कर सकते हैं। लेकिन कुछ मामलों में हमें समय को अनुकूलित करने की आवश्यकता होती है, इसलिए हम थ्रेड्स का उपयोग करते हैं , लेकिन थ्रेड में हम टोस्ट का उपयोग नहीं कर सकते हैं, जैसे कि हम उपयोग कर रहे हैं Alertdialogs AsyncTask.So में हमें पॉपअप के लिए अलग हैंडलर की जरूरत है ।

public void onSigned() {
    Thread thread = new Thread(){
        @Override
        public void run() {
            try{
                sleep(3000);
                Message message = new Message();
                message.what = 2;
                handler.sendMessage(message);
            } catch (Exception e){
                e.printStackTrace();
            }
        }
    };
    thread.start();
}

ऊपर के उदाहरण में, मैं अपने थ्रेड को 3sec में सोना चाहता हूं और उसके बाद मैं टोस्ट संदेश दिखाना चाहता हूं, इसके लिए अपने मेनथ्रेड कार्यान्वित हैंडलर में।

handler = new Handler() {
       public void handleMessage(Message msg) {
           switch(msg.what){
              case 1:
              Toast.makeText(getActivity(),"cool",Toast.LENGTH_SHORT).show();
              break;
           }
           super.handleMessage(msg);
       }
};

मैंने यहां स्विच केस का उपयोग किया है, क्योंकि यदि आपको एक ही तरह से अलग संदेश दिखाना है, तो आप हैंडलर क्लास के भीतर स्विच केस का उपयोग कर सकते हैं ... आशा है कि आपकी मदद करेगा


0

यह आमतौर पर तब होता है जब मुख्य थ्रेड पर किसी भी पृष्ठभूमि थ्रेड से कुछ कहा जाता है। उदाहरण के लिए, एक उदाहरण देखते हैं।

private class MyTask extends AsyncTask<Void, Void, Void> {


@Override
protected Void doInBackground(Void... voids) {
        textView.setText("Any Text");
        return null;
    }
}

उपरोक्त उदाहरण में, हम टेक्स्टव्यू पर पाठ सेट कर रहे हैं जो doInBackground () विधि से मुख्य UI थ्रेड में है, जो केवल एक वर्कर थ्रेड पर संचालित होता है।


0

मेरे पास एक ही समस्या थी और मैंने इसे बस टॉस को onPostExecute () में Asynctask <> के ओवरराइड फ़ंक्शन को लगाकर ठीक किया और यह काम कर गया।


-2

मैं गैर मुख्य सूत्र "संदर्भ" से संदेश दिखाने के लिए निम्न कोड का उपयोग करता हूं:

@FunctionalInterface
public interface IShowMessage {
    Context getContext();

    default void showMessage(String message) {
        final Thread mThread = new Thread() {
            @Override
            public void run() {
                try {
                    Looper.prepare();
                    Toast.makeText(getContext(), message, Toast.LENGTH_LONG).show();
                    Looper.loop();
                } catch (Exception error) {
                    error.printStackTrace();
                    Log.e("IShowMessage", error.getMessage());
                }
            }
        };
        mThread.start();
    }
}

फिर निम्नलिखित के रूप में उपयोग करें:

class myClass implements IShowMessage{

  showMessage("your message!");
 @Override
    public Context getContext() {
        return getApplicationContext();
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.