android - AsyncTask ProgressDialog 不会更新对话框消息

标签 android multithreading user-interface

我的应用程序中有一个很长的 ProgressDialog 问题。我想在第一次启动应用程序时安装一个相当大的数据库(转换为文本文档,数据库将略低于 200 页)。显然,这需要一些时间,因此我想在此过程中向用户显示一个 ProgressDialog

我正在尝试使用 AsyncTask 来完成此操作;我之前曾尝试过使用 Thread,但我陷入了与保存/恢复状态相关的问题。

进度条更新得很好。但是,我分三个阶段安装数据库,我想分别显示这些阶段,这样用户就可以对正在发生的事情有一些了解,所以栏上的每个百分点都不会花那么长时间。出于某种原因,虽然我能够在对话框中设置进度,但设置消息(或标题)似乎没有任何作用。

这是我的 AsyncTask 子类的代码:

public class InstallDbTask extends AsyncTask<Void, Integer, Void>
{
    private static final String TAG = "InstallDbTask";
    private static final int READ_RULES = 0;
    private static final int WRITE_RULES = 1;
    private static final int RW_GLOSSARY = 2;

    private ProgressDialog dialog;
    private Context context;

    public InstallDbTask(Context context) { this.context = context; }

    protected void onPreExecute()
    {
        dialog = new ProgressDialog(context);
        dialog.setProgressStyle(STYLE_HORIZONTAL);
        dialog.setCancelable(false);
        dialog.show();
    }

    protected Void doInBackground(Void... params)
    {
        ... Initialization ...

        // Number of actions to perform for progress bar
        int totalCount = rules.length;
        // Literal increment for each action
        int incrementCount = 0;
        // Integral percentage: incrementCount / totalCount * 100
        int total = 0;

        // Read rules from XML
        for(int i = 0; i < rules.length; i++)
        {
            ... Parse XML ...

            incrementCount++;
            total = (int)(((float)incrementCount / totalCount) * 100);
            publishProgress(total, READ_RULES);
        }

        incrementCount = 0;

        // Write rules to DB
        SQLiteDatabase database = new DbOpenHelper(context).getWritableDatabase();
        for(Rule r : rulesList)
        {
            ... Insert ...

            incrementCount++;
            total = (int)(((float)incrementCount / totalCount) * 100);
            publishProgress(total, WRITE_RULES);
        }

        totalCount = glossaryTerms.length;
        incrementCount = 0;

        // Write glossary to DB
        String term = null;
        for(int i = 0; i < glossaryTerms.length; i++)
        {
            ... Insert ...

            incrementCount++;
            total = (int)(((float)incrementCount / totalCount) * 100);
            publishProgress(total, RW_GLOSSARY);
        }
        database.close();

        return null;
    }

    protected void onProgressUpdate(Integer... progress)
    {
        dialog.setProgress(progress[0]);
        switch (progress[1])
        {
            case READ_RULES:
                dialog.setMessage(context.getString(R.string.load_db1));
                break;
            case WRITE_RULES:
                dialog.setMessage(context.getString(R.string.load_db2));
                break;
            case RW_GLOSSARY:
                dialog.setMessage(context.getString(R.string.load_db3));
                break;
        }
    }

    protected void onPostExecute(Void result)
    {
        dialog.dismiss();
    }
}

onProgressUpdate 方法中的情况已正确到达,ProgressDialog 只是没有收到消息,可以这么说。我做错了什么吗?

最佳答案

您必须在显示对话框之前设置初始消息。否则在 onProgressUpdate() 中调用 dialog.setMessage() 无效。

要修复您的代码,您必须添加 dialog.setMessage("Some initial message")(消息字符串可以是 "",但不能是null) 在调用 dialog.show() 之前:

protected void onPreExecute()
{
    dialog = new ProgressDialog(context);
    dialog.setProgressStyle(STYLE_HORIZONTAL);
    dialog.setCancelable(false);
    dialog.setMessage("Installing database, please wait");
    dialog.show();
}

关于android - AsyncTask ProgressDialog 不会更新对话框消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7696489/

相关文章:

c++ - 使用 C++ GUI 应用程序检查网络状态的 QT

java - Java 中的线程 : How to lock an object?

java - 执行者与线程

python - Tkinter Checkbutton 不会在颜色更改后保留其复选标记

android activity隐藏太棒,全屏

android getSharedPreferences 错误 : Map value without name attribute: boolean

java - 泛型类型枚举和静态导入导致方法不明确问题

android - 如何将 HttpEntity 转换为 JSON?

java - 如何将消息发送到在另一个处理程序中创建的临时 channel ?

java - 使用 jButton 将数据保存到 HashMap 中