我有这段代码:
MyClass tmp = new MyClass();
tmp.setParam1(1);
tmp.SetParam2("Test");
tmp.setParam3("Test");
...
然后我
tmp.heavyCalc();
在这个重度计算操作期间,我必须更新UI中的进度条,并向用户显示它正在使用进度条中的更新以及要显示的一些文本。 现在它不起作用,因为我没有使用线程,应用程序被卡住和挂起,然后突然返回进度条是100%并且所有文本都突然出现。
所以我决定让我的函数作为新线程运行。
在我班级的内部定义中,我添加了implements Runnabl
e
所以
public class MyClass implements Runnable{
然后我将heavyCalc()
函数称为我创建的新Run()
函数:
@Override
public void Run()
{
heavyCalc();
}
现在我这样做:
Thread thread = new Thread(tmp);
tmp.run();
它有效,但在UI中仍然没有任何变化,应用程序卡住,然后突然进度条100%和应用程序返回。 我缺少什么?
答案 0 :(得分:13)
您的回答:
正如其他答案所示,您应该使用thread.start()
代替tmp.run()
。
以下说明与您的问题没有直接关系,但它可以帮助您编写更好的代码,并保护您免受将来面临的错误的影响。
但是为了编写更好的代码,我的建议是使用处理程序。
通过使用处理程序,您可以在main thread
。
例如:要从为其他目的创建的类更新textView的值,您必须将此操作(更新textView)发布到主线程,因为您的自定义线程没有操作视图的权限。 / p>
在项目中使用处理程序:
1.您应该在主线程中使用Handler类创建一个实例:
public static Handler handler = new Handler();
2.从第二个线程使用这个处理程序:
YourMainThreadClass.handler.post(new Runnable() {
@Override
public void run() {
// Do Whatever
}
});
异常:您不必为progressBar使用处理程序,但您应该使用处理程序来处理相同问题中的其他视图。 ProgressBar只是一个例外,但我建议你在这种情况下使用处理程序。
答案 1 :(得分:4)
您应该使用thread.start()
启动主题,而不是手动调用。
Thread thread = new Thread(tmp);
thread.start();
答案 2 :(得分:4)
我建议您使用AsyncTask
。它的目的完全符合您的要求。它允许您运行后台操作,然后使用此类操作的结果更新UI。
答案 3 :(得分:2)
您可以使用AsyncTask。这将使它更容易。您可以使用publishProgress传递百分比,并在onProgressChange中更新UI,这将在UI线程上自动调用。
要使用AsyncTask,我们创建一个内部类,如下所示。您可以在doInBackgroun()
方法中放置任何长时间运行的代码。这是在后台线程上自动调用的 - 因此您的UI不会冻结。
如果您想更新用户界面,可以将代码放在onPreExecute()
onPostExecute
和onPublishProgress
内。
在您的情况下,您可以在onPublishProgress
方法中调用ProgressBar。
private class MyTask extends AsyncTask<Void, Integer, Void> {
@Override
protected Void doInBackground(Void... params) {
// Do Whatever
// Each time you want the progress bar to update, you
// call the publishProgress method, and pass the value
// to be passed to the progressBar.setProgress method
publishProgress(yourPercentage);
return null;
}
@Override
protected void onProgressUpdate(Integer... values) {
// update the progress bar. The value you pass in publishProgress
// is passed in the values parameter of this method
progressBar.setProgress(values[0]);
super.onProgressUpdate(values);
}
}
答案 4 :(得分:0)
然后你调用tmp.run()
,你只是在当前线程上调用方法。要创建新主题,请执行tmp.start()
。
Thread thread = new Thread(tmp);
thread.start();