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


81

मेरे पास एक गतिविधि है, और इसमें मेरी एक कक्षा है।

text=new Dynamictext(...);
text.setText("txt");

मेरे डायनेमिक टेक्स्ट जावा में मेरा यह कोड है:

public void setText(String text) {
    this.text=text;
    new asyncCreateText().execute();
    //this.createText(text);
}

//private Handler handler = new Handler();

private class asyncCreateText extends AsyncTask<Void, Void, Void> 
{
    @Override
    protected Void doInBackground(Void... unused) {
        return null;
    }

    @Override
    protected void onPostExecute(Void unused) {

    }
}

मुझे मिला:

ERROR / AndroidRuntime (5176): इसके कारण: java.lang.RuntimeException: थ्रेड के अंदर हैंडलर नहीं बना सकते हैं जिसे Looper.prepare () नहीं कहा जाता है

मैं इस त्रुटि को कैसे संभाल सकता हूं?

ERROR/AndroidRuntime(5370): java.lang.ExceptionInInitializerError
ERROR/AndroidRuntime(5370):     at com.l.start.DynamicText.setText(DynamicText.java:125)
ERROR/AndroidRuntime(5370):     at com.l.start.OpenGLRenderer.initfonts(OpenGLRenderer.java:168)
ERROR/AndroidRuntime(5370):     at com.l.start.OpenGLRenderer.init(OpenGLRenderer.java:119)
ERROR/AndroidRuntime(5370):     at com.l.start.OpenGLRenderer.onSurfaceChanged(OpenGLRenderer.java:90)
ERROR/AndroidRuntime(5370):     at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1120)
ERROR/AndroidRuntime(5370):     at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:975)

ERROR/AndroidRuntime(5370): Caused by: java.lang.RuntimeException: 
    Can't create handler inside thread that has not called Looper.prepare()
ERROR/AndroidRuntime(5370):     at android.os.Handler.<init>(Handler.java:121)
ERROR/AndroidRuntime(5370):     at android.os.AsyncTask$InternalHandler.<init>(AsyncTask.java:421)
ERROR/AndroidRuntime(5370):     at android.os.AsyncTask$InternalHandler.<init>(AsyncTask.java:421)
ERROR/AndroidRuntime(5370):     at android.os.AsyncTask.<clinit>(AsyncTask.java:152)
ERROR/AndroidRuntime(5370):     ... 6 more

क्या आप पूर्ण स्टैक ट्रेस पोस्ट कर सकते हैं? आप पृष्ठभूमि थ्रेड या कुछ से कुछ यूआई विधि बुला रहे हैं।
अलेक्जेंडरब्लॉम

1
यह इस मुद्दे पर विस्तार से बताएगा।
मज्जोश

जवाबों:


146

त्रुटि स्व-व्याख्यात्मक है ... doInBackground()एक पृष्ठभूमि थ्रेड पर चलती है, जो कि लूप के लिए अभिप्रेत नहीं है, ए से जुड़ा नहीं है Looper

आप सबसे अधिक संभावना है कि किसी हैंडलर को सीधे इंट्रोड्यूस नहीं करना चाहते हैं ... जो भी डेटा आपके doInBackground()कार्यान्वयन रिटर्न को पास करेगा onPostExecute()वह यूआई थ्रेड पर चलता है।

   mActivity = ThisActivity.this; 

    mActivity.runOnUiThread(new Runnable() {
     public void run() {
     new asyncCreateText().execute();
     }
   });

पूछे जाने वाले प्रश्न के उत्तर में लिखित आवेदन:

लगता है कि आप AsyncTaskजीएल रेंडरिंग थ्रेड से शुरू करने की कोशिश कर रहे हैं ... ऐसा न करें कि वे कभी Looper.loop()भी नहीं करेंगे । AsyncTasks वास्तव में केवल UI थ्रेड से चलाने के लिए डिज़ाइन किया गया है।

कम से कम विघटनकारी तय करना संभवत: उस किक के Activity.runOnUiThread()साथ कॉल करने के लिए होगा ।RunnableAsyncTask


1
उत्तर पूरी तरह से सही है। हालाँकि, मेरे मामले में, मुझे बस अपने कस्टम FtpUpload AsyncTask क्लास और वॉइला से कुछ टोस्ट्स (UI थ्रेड पर चलाने की कोशिश) को हटाना था।
जोश

एक ही त्रुटि मेरे पास आ रही है मैं भ्रमित हूं कि इसे कैसे हल किया जाए मैंने इसे पढ़ा विवरण लेकिन मुझे यह नहीं मिल रहा है कि कोई भी मुझे कोड स्निपेस्ट दे सकता है
एंड्रॉइड मेरे लिए सब कुछ है

32

उपरोक्त सभी उत्तर सही हैं, लेकिन मुझे लगता है कि यह सबसे आसान उदाहरण संभव है:

public class ExampleActivity extends Activity {
    private Handler handler;
    private ProgressBar progress;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        progress = (ProgressBar) findViewById(R.id.progressBar1);
        handler = new Handler();
    }

    public void clickAButton(View view) {
        // Do something that takes a while
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                handler.post(new Runnable() { // This thread runs in the UI
                    @Override
                    public void run() {
                        progress.setProgress("anything"); // Update the UI
                    }
                });
            }
        };
        new Thread(runnable).start();
    }
}

यह क्या करता है यूआई थ्रेड में एक प्रगति पट्टी को पूरी तरह से अलग थ्रेड से पोस्ट किया गया है जो गतिविधि में घोषित हैंडलर की पोस्ट () विधि से गुजरता है।

आशा है कि इससे सहायता मिलेगी!


22

आप इस तरह बैकग्राउंड थ्रेड में हैंडलर बनाएं

private void createHandler() {
        Thread thread = new Thread() {
          public void run() {
               Looper.prepare();

               final Handler handler = new Handler();
               handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                       // Do Work
                        handler.removeCallbacks(this);
                        Looper.myLooper().quit();
                   }
                }, 2000);

                Looper.loop();
            }
        };
        thread.start();
    }

न केवल समस्या को हल करता है, बल्कि बहुत व्याख्यात्मक भी है। आटे की समस्या। अगर यह चाहते हैं removeCallbacksऔर quitकब Workकिया जाता है, तो संरचना कैसे बदल जाएगी , लेकिन देरी नहीं हुई है। क्योंकि काम ज्यादा समय तक चल सकता है।
फ़रीद

12

Activity.runOnUiThread()मेरे लिए काम नहीं करता है। मैंने इस मुद्दे पर इस तरह से एक नियमित धागा बनाकर काम किया:

public class PullTasksThread extends Thread {
   public void run () {
      Log.d(Prefs.TAG, "Thread run...");
   }
}

और जीएल से इसे इस तरह से कॉल करना:

new PullTasksThread().start();

यह समाधान मेरे लिए इसे GL से कॉल करने के लिए काम किया है, लेकिन आपको यकीन है कि आप रन विधि पर Toasts कॉल नहीं कर रहे हैं !! AsyncTask ने GL से इसे कॉल करने का काम नहीं किया। धन्यवाद!
अल्बर्टो एम।

एक AsyncTask की जगह में मेरे लिए महान काम करता है। धन्यवाद!
इगोरगानापोलस्की

5

आपको यूआई थ्रेड से एसिंत्स्क चलाने की कोशिश करें। जब मैंने ऐसा नहीं किया तो मुझे इस मुद्दे का सामना करना पड़ा!


3

इसे इस्तेमाल करे

    Handler mHandler = new Handler(Looper.getMainLooper());
                        mHandler.post(new Runnable() {
                            @Override
                            public void run() {
 //your code here that talks with the UI level widgets/ try to access the UI 
//elements from this block because this piece of snippet will run in the UI/MainThread.                                     
                            }
                        });

1
थोड़ा स्पष्टीकरण जोड़ने की कोशिश करें। कोड केवल SO पर उत्तर की बहुत सराहना नहीं करते हैं।
ऐलेक्सी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.