Android Dialog和AsyncTask导致UI冻结

时间:2012-09-11 20:52:00

标签: java android multithreading android-asynctask android-ui

所以,在我的Dialog中,我有一个启动Asynctask下载器的按钮,从我的服务器获取一些文件;这工作得很好。但是,我想解除当前的Dialog并显示单击按钮上的ProgressDialog。我该如何处理这个问题?

目前,如果我点击按钮(我的Dialog中的一个元素),整个用户界面会在下载器从服务器下载文件时冻结。下载程序完成任务后,将显示进度对话框。

我的代码看起来像这样

MainActivity{

    Dialog dialog;
    ProgressDialog progress;

    onCreate(){
        dialog = new Dialog(this);
        progress = new ProgressDialog(this);
        dialog.setContentView(Some View Resource With My Button);
        someMethod();
        dialog.show();
    }

    someMethod(){
        Button button = (Button) dialog.findViewById(resource of button);
        button.setOnClickListener(new OnClickListener(){

            onClick(){
                dialog.dismiss();
                progress.show();
                new DownloaderAsyncTask(progress).execute().get();
            }

                    //go to another activity when download finished

        });
    }

    private class DownloaderAsyncTask extends AsyncTask<Void, Void, Void>{

        ProgressDialog progress;

        DownloaderAsyncTask(ProgressDialog progress){
            this.progress = progress;
        }

        doInBackGround(){
            //Downloading
        }

        onPostExecute(){
            //Kill connection
            this.progress.dismiss();
        }

    }

}

感谢。如果您需要任何其他信息,请告诉我。

2 个答案:

答案 0 :(得分:6)

new DownloaderAsyncTask(progress).execute().get();

我真的不知道为什么AsyncTaskget()方法 - 它基本上将异步进程转换为同步进程,因为它会阻塞并等待结果。这就是用户界面冻结的原因。

如果您想等待下载程序完成然后执行其他操作,那就是onPostExecute(...)的用途。

答案 1 :(得分:2)

您的UI线程被冻结,因为您调用了get()。不要那样做。相反,启动您的AsyncTask并制作包含您希望在下载结束时执行的代码的onPostExecute()调用方法,如下所示(更多/更少):

someMethod() {
        Button button = (Button) dialog.findViewById(resource of button);
        button.setOnClickListener(new OnClickListener(){

            onClick(){
                dialog.dismiss();
                progress.show();
                new DownloaderAsyncTask().execute();
            }
        });

private void downloaderFinished() {
    this.progress.dismiss();
    /// go to next activity.
}

private class DownloaderAsyncTask extends AsyncTask<Void, Void, Void>{

        doInBackGround(){
            //Downloading
        }

        onPostExecute(){
            //Kill connection
            downloaderFinished();
        }
    }

这就是async代表的方式,嗯,异步,所以调用get()会杀死所有的好处。