Looper.prepare () çağrılmamış iş parçacığı içinde işleyici yaratılamıyor


81

Bir Aktivitem var ve bunda bir dersim var.

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

DynamicText java'mda bu koda sahibim:

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

    }
}

Alırım:

HATA / AndroidRuntime (5176): Neden olduğu: java.lang.RuntimeException: Looper.prepare () çağrılmamış iş parçacığı içinde işleyici oluşturulamıyor

Bu hatayı nasıl halledebilirim?

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

Tam yığın izini gönderebilir misiniz? Arka plan iş parçacığından veya başka bir şeyden bazı UI yöntemlerini çağırıyor gibisiniz.
alexanderblom

1
Bu , sorunu ayrıntılı olarak açıklayacaktır.
mjosh

Yanıtlar:


146

Hata kendinden açıklamalıdır ... doInBackground()bir arka plan iş parçacığı üzerinde çalışır, döngü oluşturması amaçlanmadığı için bir Looper.

Büyük olasılıkla bir İşleyiciyi doğrudan somutlaştırmak istemezsiniz ... doInBackground()uygulamanızın döndürdüğü veriler onPostExecute(), UI iş parçacığında çalıştırılan hangi verilere aktarılırsa verilsin.

   mActivity = ThisActivity.this; 

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

SORUDA GÖRÜNEN Yığın İzinden Sonra Eklendi:

Görünüşe göre AsyncTaskbir GL oluşturma iş parçacığından başlatmaya çalışıyorsunuz ... bunu yapma çünkü onlar da asla yapmayacaklar Looper.loop(). AsyncTasks gerçekten yalnızca UI iş parçacığından çalıştırılmak üzere tasarlanmıştır.

En az rahatsız edici çözüm, muhtemelen sizi başlatan Activity.runOnUiThread()bir Runnabletelefonla aramak olacaktır AsyncTask.


1
Cevap tamamen doğru. Ancak, benim durumumda, özel FtpUpload AsyncTask sınıfımdan ve işte bazı Toast'ları (UI iş parçacığında çalıştırmayı denemek) kaldırmak zorunda kaldım.
Josh

aynı hata i açıklamayı okuyun ama kimse bana kodu verebilir nasıl almıyorum nasıl çözüleceğini kafamı karıştırdı bana geliyor snippest lütfen
Android benim için her şeydir

32

Yukarıdaki tüm cevaplar doğru, ancak bunun mümkün olan en kolay örnek olduğunu düşünüyorum:

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

Bunun yaptığı şey, faaliyette bildirilen işleyicinin post () yönteminden geçen tamamen farklı bir iş parçacığından UI iş parçacığındaki bir ilerleme çubuğunu güncellemektir.

Umarım yardımcı olur!


22

Bu şekilde arka planda işleyici oluşturursunuz

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

Sadece sorunu çözmez, aynı zamanda çok açıklayıcıdır. Küçük problemli hamur. Yapısı istenirse nasıl değişir removeCallbacksve quitne zaman Workyapılır, ancak gecikme olmaz. Çünkü iş önceden tanımlanmış gecikmeden daha uzun sürebilir.
Farid

12

Activity.runOnUiThread()benim için çalışmıyor. Bu şekilde normal bir iş parçacığı oluşturarak bu sorunu çözdüm:

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

ve GL güncellemesinden şu şekilde çağırır:

new PullTasksThread().start();

Bu çözüm benim için GL'den aradım ama Toasts on run yöntemini çağırmadığınızdan emin olmalısınız !! AsyncTask bunu GL'den arayarak çalışmadı. Teşekkürler!
Alberto M.

Bir AsyncTask'ı değiştirirken benim için harika çalışıyor. Teşekkürler!
IgorGanapolsky

5

UI iş parçacığından sizi eşzamansız olarak çalıştırmayı deneyin. Ben de aynısını yapmadığım zamanlarda bu sorunla karşılaştım!


3

Bunu dene

    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
Küçük bir açıklama eklemeye çalışın. SO'da yalnızca kod yanıtları pek beğenilmez.
Alexei
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.