首页 文章

无法在未调用Looper.prepare()的线程内创建处理程序

提问于
浏览
74

我有一个活动,并且我有一个 class .

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

在我的DynamicText java中,我有这样的代码:

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

6 回答

  • 4

    错误是不言自明的... doInBackground() 在后台线程上运行,因为它不打算循环,所以没有连接到 Looper .

    您很可能根本不想直接实例化Handler ... doInBackground() 实现返回的任何数据都将传递给在UI线程上运行的 onPostExecute() .

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

    ADDED FOLLOWING THE STACKTRACE APPEARING IN QUESTION:

    看起来你正试图从一个GL渲染线程开始 AsyncTask ...也许't do that cos they won' t也是 Looper.loop() . AsyncTasks实际上只能从UI线程运行 .

    破坏性最小的修复可能是用 Runnable 调用 Activity.runOnUiThread() 来启动你的 AsyncTask .

  • 2

    以上所有答案都是正确的,但我认为这是最简单的例子:

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

    这样做是从一个完全不同的线程更新UI线程中的进度条,该线程通过活动中声明的处理程序的post()方法传递 .

    希望能帮助到你!

  • 11

    您以这种方式在后台线程中创建处理程序

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

    Activity.runOnUiThread() 对我不起作用 . 我通过这种方式创建一个常规线程来解决这个问题:

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

    并以这种方式从GL更新中调用它:

    new PullTasksThread().start();
    
  • 143

    尝试从UI线程运行asyntask . 当我不做同样的事情时,我遇到了这个问题!

  • 28

    试试这个

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

相关问题