我有一个简单的函数,可以在获取数据时显示加载微调器(通常需要7秒左右)
private void load_data(View v)
{
task_complete = false;
progressBar = new ProgressDialog(v.getContext());
progressBar.setCancelable(false);
progressBar.setMessage("Fetching data ...");
progressBar.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progressBar.show();
try
{
Log.v("thread", "Starting thread");
new Thread(new Runnable()
{
public void run()
{
while(!task_complete)
{
fetch_data();
try
{
Thread.sleep(1000);
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
progressBar.dismiss();
}
}).start();
Log.v("thread", "Thread finished successfully");
}
catch(Exception e)
{
Log.v("thread", "fail "+e.toString());
}
}
我遇到的问题是onClick通过
调用该函数load.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
load_data(v);
show_data(v); // shows the data on a spinner
}
});
当我第二次按下加载按钮时出现错误。我的日志确实显示
Starting thread
Thread finished successfully
但不知何故,该应用程序因错误而死亡
03-27 02:48:39.282: E/AndroidRuntime(956): Uncaught handler: thread Thread-9 exiting due to uncaught exception
03-27 02:48:39.293: E/AndroidRuntime(956): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
03-27 02:48:39.293: E/AndroidRuntime(956): at android.view.ViewRoot.checkThread(ViewRoot.java:2683)
如果有人能告诉我或向我解释导致错误的原因,我将不胜感激
答案 0 :(得分:2)
问题是你的progressBar.dismiss();在另一个线程中执行,使其在UI线程中运行,执行以下操作:
runOnUiThread(new Runnable() {
@Override
public void run() {
progressBar.dismiss();
}
});
答案 1 :(得分:1)
ProgressDialog
是一个视图,您只能在UI线程(或主线程)中访问它。使用AsyncTask
代替线程。
修改强>
This official link将帮助您掌握AsyncTask。要记住的是doInBackground()方法在单独的线程中运行,您应该在其中放置数据加载方法,即fetch_data()。一旦方法完成执行,将调用onPostExecute(),它将在UI线程上运行,您可以在其中关闭对话框。您可以在onPreExecute()方法中启动对话框
虽然在此上下文中您不需要onProgressUpdate()方法,但只需FYI,它用于在使用publishProgress()调用(如果您将来使用AsyncTask)加载仍在工作时更新UI线程中的Views。
PS:只有doInBackground()方法在单独的线程中运行,其他每个方法都在UI线程中运行。
,关于不在UI之外的任何其他线程中访问View的规则仍然适用。