Невозможно создать обработчик внутри потока, который не вызвал Looper.prepare()
У меня есть Activity, и у меня есть класс.
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
Ответы
Ответ 1
Ошибка не требует пояснений... doInBackground()
работает на фоновом потоке, который, поскольку он не предназначен для цикла, не связан с Looper
.
Скорее всего, вы не хотите напрямую создавать экземпляр обработчика... любые данные, полученные вашей реализацией реализации doInBackground()
, будут переданы в onPostExecute()
, который выполняется в потоке пользовательского интерфейса.
mActivity = ThisActivity.this;
mActivity.runOnUiThread(new Runnable() {
public void run() {
new asyncCreateText().execute();
}
});
ДОБАВЛЯТЬ СЛЕДУЮЩИЙ СТЕКЛЕР, ВЫЯВЛЯЕМЫЙ ВОПРОС:
Похоже, вы пытаетесь запустить AsyncTask
из потока рендеринга GL... не делайте этого, потому что они никогда не будут Looper.loop()
. AsyncTasks действительно предназначены для запуска только из потока пользовательского интерфейса.
Наименее разрушительное исправление, вероятно, должно было бы вызвать Activity.runOnUiThread()
с помощью Runnable
, который запускает ваш 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();
}
}
Что это значит - обновить индикатор выполнения в потоке пользовательского интерфейса из совершенно другого потока, прошедшего через метод post() обработчика, объявленного в действии.
Надеюсь, что это поможет!
Ответ 3
Вы создаете обработчик в фоновом потоке таким образом
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();
}
Ответ 4
Activity.runOnUiThread()
не работает для меня. Я работал над этой проблемой, создав регулярный поток таким образом:
public class PullTasksThread extends Thread {
public void run () {
Log.d(Prefs.TAG, "Thread run...");
}
}
и вызывая его из обновления GL следующим образом:
new PullTasksThread().start();
Ответ 5
Попробуйте запустить asyntask из потока пользовательского интерфейса. Я столкнулся с этой проблемой, когда я не делал то же самое!
Ответ 6
Попробуйте это
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.
}
});