当一个Activity正在加载时,显示一个进度条

20

我有一个ListActivity,它根据列表选择启动另一个Activity。第二个Activity需要从互联网加载大量数据,因此在用户单击项目和Activity显示之间存在明显的延迟。

这是一个问题,因为目前我没有办法告诉用户他们的点击正在被处理(即使只改变所选列表项的颜色也足够了,但我找不到一个好的方法来实现)。理想情况下,在第二个Activity加载时,我希望能够显示一个未确定的ProgressDialog

我尝试了几种不同的方法,但没有一种像期望的那样工作。


我尝试了以下方法:

  • 在第一个ActivityAsyncTask中检索可序列化数据(不是全部,而是部分),并将其作为额外参数传递给第二个Activity。这并没有很好地解决问题,因为在onPreExecute()中创建的ProgressDialog没有立即显示(由于某种原因,它似乎被doInBackground()中执行的处理所延迟)。

这是那段代码:

AsyncTask<String, Void, String> read = new AsyncTask<String, Void, String>() {
    Dialog progress;

    @Override
    protected void onPreExecute() {
        progress = ProgressDialog.show(SearchActivity.this, 
                "Loading data", "Please wait...");
        super.onPreExecute();
    }

    @Override
    protected String doInBackground(String... params) {
        DatasetReader reader = new DatasetReader();
        reader.setFundID(params[0]);
        reader.addDatsets(FundProfile.datasets);
        reader.populate();
        return reader.toString();
    }

    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        progress.dismiss();
    }
};
read.execute(selectedItem.getUniqueID());
try {
    action = new Intent(SearchActivity.this, FundProfile.class);
    action.putExtra("data", read.get());
} catch(Exception ex) {
    ex.printStackTrace();
}
  • 在第二个Activity的onCreate()方法中(这样根本不起作用):

    requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
    setProgressBarVisibility(true);

以下是第二种方法的onCreate()方法:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    this.setTitleColor(Color.WHITE);
    requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
    setProgressBarVisibility(true);

    try {
        setContentView(R.layout.fund_profile);
        // init some data
        setProgressBarVisibility(false);
    } catch(Exception ex) {
        FundProfile.this.finish();
    }
}

1
你尝试过哪些不同的方法?能分享一下你的尝试吗? - Cristian
我很惊讶第一种方法没有奏效。在onPreExecute()中显示的ProgressDialog不应该被doInBackground()中的代码所阻塞,也许你的代码还有其他问题? - dave.c
可能吗?我已经添加了相关的代码。 - Adam
3个回答

16
如果您有长时间的操作,无论是否显示活动,都不应该在onCreate中执行它们,因为这将冻结UI。由onCreate设置的UI将不会出现,在onCreate调用完成之后,UI将无响应。
似乎您可以启动第二个活动并显示进度条(或 requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); ),然后启动一个ASyncTask,该任务将负责一旦检索到数据,更新您的UI。

是的,我想到了这是正确的方法(在另一个线程中加载数据),但我现在想避免它...但我咬了咬牙,用了这种方式(AsyncTask使得这不那么痛苦)。 - Adam

3
将创建Intent的步骤 — 以及任何需要在AsyncTask完成后执行的步骤 — 移动到onPostExecute中:
@Override
protected void onPostExecute(String result) {
    super.onPostExecute(result);
    progress.dismiss();
    Intent action = new Intent(SearchActivity.this, FundProfile.class);
    action.putExtra("data", result);
    // ... do more here
}

问题在于 AsyncTask.get()阻塞了线程直到任务完成。因此,在上面的代码中,UI线程被阻塞,进度对话框无法出现,直到任务完成。

3

第一个活动的视图将一直停留在屏幕上,直到整个onCreate()方法完成,因此我从未看到进度条。 - Adam
你在onCreate()方法中什么时候调用setContentView() - Will Tate
进度条显示完毕后的第一件事。我已经在原帖中更新了这些信息。 - Adam
好的,看起来你将进度条设置为可见,然后立即将其设置为不可见。 - Will Tate
我注释掉了一些代码,该代码检索数据并填充视图(实际上,我创建了一些自定义视图来填充它们自己的数据..)。 - Adam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接