我正在使用大量数据更新数据库(SQLite),这需要几分钟。我在一个线程上这样做。同时我想通过Toast显示更新的进度(25%,50%等)。由于我在一个线程中,我需要使用runOnUiThread()函数来运行Toast。像这样:
getActivity().runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(getActivity(),"Updating the database...", Toast.LENGTH_SHORT).show();
}
});
当工作量不大时工作正常。现在确实如此,根本没有显示吐司。
我一直在寻找为toast的线程设置非常高优先级的方法,但没有成功。也许我可以首先绕过使用线程进行吐司?
感谢您的见解!
编辑: 实际上,toast 正在运行,但在完成所有工作后会显示。我想通知用户完成更新的百分比,所以我需要在更新期间显示toast,而不是之后。
我尝试删除工作负载(没有数据库更新,只有在要添加到数据库的for循环内部的Log.d)。尽管在循环内部调用了runOnUiThread()
方法,但在循环结束后会显示toast。
编辑2: 我清理完代码并重新开始后,设法做了我想做的事。我发布了我用作以下答案的代码。
答案 0 :(得分:0)
清理完初始线程后,我设法让一些工作正常。我在这里发布代码,因为它可以用作模板来执行特定任务:
运行一个初始线程,该线程定期执行任务一定次数(此处收集一些数据)。在给定次数之后,收集的数据被推送到数据库,并通知用户进程的进展(这需要很长时间)。
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask(){
long t0 = System.currentTimeMillis();
@Override
public void run() {
if(System.currentTimeMillis() - t0 > EXPERIMENT_DURATION ){
processData(dataArrayList); // custom tasks - see below
cancel();
}else {
dataArrayList = collectData(); // custom tasks
}
}
}, 0, INTERVAL);
使用:
void processData(Arraylist<Data> dataArrayList){
for(Data data : dataArrayList){
// show progression to the user
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
int percent = Math.round(((float)dataArrayList.indexOf(data))/((float)dataArrayList.size())*100)
Toast.makeText(getActivity(),"Update: " + Integer.toString(percent) + "%", Toast.LENGTH_LONG).show();
}
});
updateDataBase(data);
}
}
答案 1 :(得分:-1)
我强烈建议您使用 AsyncTask
。
AsyncTask
在其他工作Thread
中执行,但它提供了在用户界面Thread
,publishProgress(String ...)
中执行的方法。然后,您可以通过覆盖onProgressUpdate(String ...)
来自定义。
编辑:正如在评论中所读到的,AsyncTask
不是一个选项,因为:
所有AsyncTask共享一个Thread
(它们不会像我预期的那样在workers
上运行)
对于长时间运行的Task
s,所有其他AsyncTasks
(系统和您的)将被暂停
这包括来自图书馆的AsyncTask