Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't create handler inside thread which has not called Looper.prepare()

I have an Activity, and in that I have a class.

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

in my DynamicText java I have this code:

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

I get:

ERROR/AndroidRuntime(5176): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()

How can I handle this error?

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 
like image 305
lacas Avatar asked Feb 15 '11 21:02

lacas


People also ask

What is looper prepare?

android.os.Looper. Class used to run a message loop for a thread. Threads by default do not have a message loop associated with them; to create one, call prepare() in the thread that is to run the loop, and then loop() to have it process messages until the loop is stopped.

What is looper message and handler?

Looper , Handler , and HandlerThread are the Android's way of solving the problems of asynchronous programming. They are not old school, but a neat structure on which a complex android framework is built.

What is a handler in Android?

A Handler allows you to send and process Message and Runnable objects associated with a thread's MessageQueue . Each Handler instance is associated with a single thread and that thread's message queue. When you create a new Handler it is bound to a Looper .

What is UI thread in Android?

User Interface Thread or UI-Thread in Android is a Thread element responsible for updating the layout elements of the application implicitly or explicitly. This means, to update an element or change its attributes in the application layout ie the front-end of the application, one can make use of the UI-Thread.


2 Answers

The error is self-explanatory... doInBackground() runs on a background thread which, since it is not intended to loop, is not connected to a Looper.

You most likely don't want to directly instantiate a Handler at all... whatever data your doInBackground() implementation returns will be passed to onPostExecute() which runs on the UI thread.

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

ADDED FOLLOWING THE STACKTRACE APPEARING IN QUESTION:

Looks like you're trying to start an AsyncTask from a GL rendering thread... don't do that cos they won't ever Looper.loop() either. AsyncTasks are really designed to be run from the UI thread only.

The least disruptive fix would probably be to call Activity.runOnUiThread() with a Runnable that kicks off your AsyncTask.

like image 157
Reuben Scratton Avatar answered Nov 17 '22 03:11

Reuben Scratton


All the answers above are correct, but I think this is the easiest example possible:

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

What this does is update a progress bar in the UI thread from a completely different thread passed through the post() method of the handler declared in the activity.

Hope it helps!

like image 30
Lisandro Avatar answered Nov 17 '22 03:11

Lisandro