我有一个活动,其中我有一堂课。
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) {
}
}
我得到:
错误/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
该错误是不言自明的... doInBackground()
在后台线程上运行,因为它不打算循环,因此未连接到 Looper
。
您很可能根本不想直接实例化一个处理程序...您的 doInBackground()
实现返回的任何数据都将传递给在 UI 线程上运行的 onPostExecute()
。
mActivity = ThisActivity.this;
mActivity.runOnUiThread(new Runnable() {
public void run() {
new asyncCreateText().execute();
}
});
在出现问题的堆栈跟踪之后添加:
看起来您正在尝试从 GL 渲染线程启动 AsyncTask
...不要这样做,因为他们也不会 Looper.loop()
。 AsyncTasks 真正设计为仅从 UI 线程运行。
破坏性最小的解决方法可能是调用 Activity.runOnUiThread()
并使用启动您的 AsyncTask
的 Runnable
。
上面所有的答案都是正确的,但我认为这是最简单的例子:
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() 方法传递。
希望能帮助到你!
您以这种方式在后台线程中创建处理程序
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();
}
Work
完成时需要 removeCallbacks
和 quit
结构将如何变化,但未达到延迟。因为工作可能会持续更长时间的预定义延迟。
Activity.runOnUiThread()
对我不起作用。我通过这种方式创建一个常规线程来解决这个问题:
public class PullTasksThread extends Thread {
public void run () {
Log.d(Prefs.TAG, "Thread run...");
}
}
并以这种方式从 GL 更新中调用它:
new PullTasksThread().start();
尝试从 UI 线程运行您的异步任务。当我不这样做时,我遇到了这个问题!
尝试这个
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.
}
});
对于所有 Kotlin 爱好者,这里是给你的代码
Handler(Looper.getMainLooper()).post {
// any UI update here
}