【问题标题】:ProgressDialog not shown in AsyncTaskProgressDialog 未显示在 AsyncTask 中
【发布时间】:2012-08-13 16:16:22
【问题描述】:

我在 SDCard 上有一个巨大的数据库 (40MB)。我需要获取数据,查询中有LIKE,这很慢。

数据库请求大约需要 5 秒。因此,我需要使用ProgressDialog 异步执行此操作。

我用AsyncTask 尝试过,但问题出在ProgressDialog
它是这样实现的:

private class GetDataFromLangDB extends AsyncTask<String, String, String> {

    private final ProgressDialog dialog = new ProgressDialog(TranslAndActivity.this);

    @Override
    protected void onPreExecute() {
        super.onPreExecute();

         urDBCursor.close();
         curDBCursor = null;
         scaAdapter = null;

         this.dialog.setMessage("Loading data...");
         this.dialog.show();

    } 

    @Override
    protected String doInBackground(String... whatSearch) {
        String result = "";

        if (myDatabaseAdapter != null) {
            curDBCursor = myDatabaseAdapter.fetchAll(whatSearch[0]);
        }
        return result;
    }

    @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);

            if (this.dialog.isShowing()) {
                this.dialog.dismiss();
            }

            prepareListView();
    }
}

问题是 ProgressDialog 在 DB 请求期间没有显示。 完成数据库查询后,它会在屏幕上短暂闪烁。当用户尝试 在数据库请求期间点击屏幕,UI 被冻结,在数据库请求之后 显示有关“未响应”的消息。

我用这种方式尝试了一个线程:

public void startProgress(View view, final String aWhatSearch) {

        final ProgressDialog dialog = new ProgressDialog(MyActivity.this);
        if (curDBCursor != null){
            curDBCursor.close();
            curDBCursor = null;
        }

        dialog.setMessage("Loading data...");
        dialog.show();
        Runnable runnable = new Runnable() {
            public void run() {
                curDBCursor = myDatabaseAdapter.fetchAll(aWhatSearch);
                // dirty trick
                try {
                    Thread.sleep(250); // it must be here to show progress
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                handler.post(new Runnable() {
                    public void run() {
                        if (dialog.isShowing()) {
                            dialog.dismiss();
                        }
                        prepareListView();
                    }
                });

            }
        };
        new Thread(runnable).start();
    }

结果是一样的,但是当我使用 Thread.sleep(250) 的技巧时; ProgressDialog 在数据库请求期间显示。但它不旋转, 在 DB 请求期间它看起来被冻结了。

DB 的东西是这样调用的(点击搜索按钮后):

btnSearchAll.setOnClickListener(new OnClickListener() {
    public void onClick(View v) {
        // AsyncTask
        new GetDataFromLangDB().execute(edtTextToSearch.getText().toString());

        // or Thread 
        //startProgress(null, edtTextToSearch.getText().toString());
    }
});

我在 SO 中发现了很多这样的问题,但没有什么对我有用。 难道DB在SD卡上?

【问题讨论】:

  • 数据库在 SD 卡上不是这个原因。您可以粘贴调用 AsyncTask 的代码部分吗?
  • 调用代码很简单——按钮点击,更新

标签: android database android-asynctask progressdialog


【解决方案1】:

像这样声明你在类(活动)级别的对话框

private ProgressDialog dialog = null;

显示进度对话框并在您想要开始忙碌工作时调用 AsyncTask 类..如 onButton click 或任何

dialog = ProgressDialog.show(this,"Sending Email to your account please! wait...", true);
SendingEmailTask task = new SendingEmailTask();
String s = "";
task.execute(s);

一样创建你的内部类
private class SendingEmailTask extends AsyncTask<String, Void, String> {

    protected String doInBackground(String... urls) {
         //do your work here..
         // like fetching the Data from DB or any
         return null;
       }

       @Override
       protected void onPostExecute(String str) {
           //hide progress dialog here
           dialog.dismiss();
       }
}

如果有帮助请告诉我!

【讨论】:

  • 感谢您的回答,但没有帮助。还是一样。我将尝试使用 AsyncQueryHandler 回答 sinisha,或者尝试将其包装到 Service
  • 好吧,我没有检查数据库加载,所以不确定,但我这样做是为了发送电子邮件等,它对我来说很好......祝 AsyncQueryHandler 好运
【解决方案2】:

也许这个SO answer 可以帮助你。它看起来像类似的问题。尝试使用AsyncQueryHandler 查询您的数据库

【讨论】:

    【解决方案3】:

    我将对话框的定义放入 AsyncTask 类中,它对我来说很好用。 看看这个例子(你必须以你的类的名字改变 NAMEOFCLASS:

    private class doInBackground extends AsyncTask<Integer, Integer, Void> {
    
       final ProgressDialog dialog = new ProgressDialog(NAMEOFCLASS.this) {
    
        @Override
        protected void onPreExecute() {
            dialog.setCancelable(false);
            dialog.setTitle(getString(R.string.daten_wait_titel));
            dialog.setIcon(R.drawable.icon);
            dialog.setMessage(getString(R.string.dse_dialog_speichern));
            dialog.show();
        }
    
        @Override
        protected void onCancelled() {
            dialog.cancel();
        }
    

    ....

        @Override
        protected void onProgressUpdate(Integer... values) {
                       // DO YOUR UPDATE HERE
        }
    
        @Override
        protected void onPostExecute(Void result) {
            dialog.dismiss();
                    }
    
    }
    

    【讨论】:

    • 我认为他对对话框的定义是在AsyncTask中。他使用 this.dialog 引用它
    • Yes 对话框的定义在 AsyncTask 中。因此,我很困惑那里有什么问题。也许在繁重的数据库负载期间 - > 由于 SQLite 驱动程序繁忙,设备没有响应...... **也许我需要为此提供服务(?)**
    • 好的。这是正确的。那么唯一的区别就是 Super.OnPreExcecute();也许删除这一行会有所帮助。
    • @Peter 你能给我们logcat吗?
    • @JackTools.Net 如果他删除 super.OnPreExecute 肯定会导致应用程序崩溃
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-13
    • 2015-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多