编辑:已解决。对不起,伙计们,我突然想到,虽然我的数据加载是在后台线程中发生的,但解析数据的回调却没有。数据的解析花费了很长时间,这就是锁定我的线程的原因。
编辑:我注意到我的首要问题(ProgressDialog 不再旋转)可能是由我使用 ProgressDialog 的问题引起的,而不是 UI 线程被阻塞。如果是这种情况,我该如何解决?
编辑:澄清一下,这不会永远锁定整个程序。加载完所有内容后,将关闭进度对话框,并启动新活动。我的问题是,当它正在加载时,整个 UI 被锁定(即进度对话框停止旋转)
TL;DR:doInBackground() 中的 Thread.sleep() 正在锁定 UI 线程
我有一个应用程序,当一个特定的活动打开时,它开始从我的后端在后台加载大量数据,例如,与计划相关的大量数据。该信息不会立即使用,但可以在用户尝试访问它时使用(即通过单击计划按钮并启动计划活动)。
如果用户在单击计划按钮之前稍等片刻,所有数据都会加载,计划活动将打开,并显示一切都很好。我的问题是如果他们在数据加载之前单击按钮。
我的解决方案是创建一个显示 ProgressDialog 的 ASyncTask,同时定期检查数据是否已完成加载,否则休眠。它通过一些应用程序范围的布尔变量知道数据已完成加载。我的问题是,即使 Thread.sleep() 在 doinbackground() 中运行,它仍然会锁定 UI 线程。
我正在使用自定义 ASyncTask,定义如下:
public class LoadWithProgressDialog extends AsyncTask<Void, Void, Boolean>{
private ProgressDialog pd; //the progress dialog
private String title; //the title of the progress dialog
private String message; //the body of the progress dialog
private Runnable task; //contains the code we want to run in the background
private Runnable postTask; //execute when the task ends
private Context c;
public LoadWithProgressDialog(Context context,String t, String m,Runnable r, Runnable postR){
super();
c = context;
task = r;
postTask = postR;
title = t;
message = m;
}
@Override
protected void onPreExecute(){
pd = ProgressDialog.show(c,title, message, false, false);
}
@Override
protected Boolean doInBackground(Void... params) {
task.run();
return true;
}
@Override
protected void onPostExecute(Boolean result) {
pd.dismiss();
if(postTask != null)
postTask.run();
}
并通过(例如)调用它:
if(loadingSchedule){
LoadWithProgressDialog lwpd = new LoadWithProgressDialog(thisClass,"Loading","Loading Schedule", new Runnable() {
public void run(){
while(loadingSchedule){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
},new Runnable() {
public void run(){
Intent i= new Intent(thisClass, Schedule.class);
i.putExtra("numberIneed",index);
startActivity(i);
}
});
lwpd.execute();
(我将全局变量的访问缩短为“loadingSchedule”以使其更易于阅读)
如何使它不锁定 UI 线程?