AsyncTask progressdialog没有显示,doInBackground阻止UI

时间:2014-03-26 17:29:44

标签: java android android-asynctask

我一直在尝试在检索数据时使progressdialog正常工作。

我使用此链接Implement android splash screen while loading data让我开始,但似乎我无法让它正常工作。

到目前为止,它没有显示任何进度条,因为我认为函数fillMyTickets会阻止UI线程,因此不会显示对话框。我不明白如何解决这个问题。通过阅读Stackoverflow我找到了解决方案,例如在AsyncTask中使用onProgressUpdate函数,但这不是我想要的。我只需要一个等待对话框,说明HTTP调用结束后下载和消失。

exampleFragment.java

中的Asynctask函数
private ProgressDialog dialog;
private class PrefetchData extends AsyncTask<Void, Void, Void> {

@Override
protected void onPreExecute() {
    super.onPreExecute();
    dialog = new ProgressDialog(getActivity());
    dialog.setMessage("Downloading..");
    dialog.setIndeterminate(true);
    dialog.setCancelable(true);
    dialog.show();
}

@Override
protected Void doInBackground(Void... arg0) {
    fillMyTickets();
    return null;
}

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

fillMyTickets函数在 exampleFragment.java

private void fillMyTickets() {
        HttpReader httpReader = new HttpReader();
        httpReader
                .setOnResultReadyListener(new HttpReader.OnResultReadyListener() {
                    @Override
                    public void resultReady(String result) {

                        JsonHelper jsonHelper = new JsonHelper();
                        tickets = jsonHelper.getTickets(result);
                    }
                });
        httpReader
                .execute(url);
    }

onAttach(活动活动)执行AsyncTask的功能

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
     new PrefetchData().execute();
}

同样,当在AsyncTask的 onPostExecute 中评论 dialog.dismiss()时,对话框确实会显示但是当然不会关闭。

3 个答案:

答案 0 :(得分:1)

您正在调用一个注册侦听器并下载某些数据的方法,但在下载数据之前,您将从doInBackground返回并关闭该对话框,因此您的对话框正在显示并隐藏。尝试修改代码并在完成下载后关闭对话框:

private ProgressDialog dialog;
private class PrefetchData extends AsyncTask<Void, Void, Void> {

@Override
protected void onPreExecute() {
    super.onPreExecute();
    dialog = new ProgressDialog(getActivity());
    dialog.setMessage("Downloading..");
    dialog.setIndeterminate(true);
    dialog.setCancelable(true);
    dialog.show();
}

@Override
protected Void doInBackground(Void... arg0) {
    HttpReader httpReader = new HttpReader();
    httpReader.setOnResultReadyListener(new HttpReader.OnResultReadyListener() {
                @Override
                public void resultReady(String result) {
                    JsonHelper jsonHelper = new JsonHelper();
                    tickets = jsonHelper.getTickets(result);
                    //finished the download and we dismiss the dialog
                    dialog.dismiss();
                }
            });
    httpReader.execute(url);
    return null;
}

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

希望它有所帮助!

答案 1 :(得分:1)

虽然我建议您使用Volley库来执行异步网络请求(具有重试策略,线程池执行程序的内容,以及其他一些可以扩展和修改的美味内容),但在过去的项目中我会这样做。我使用了一个带有进度对话框的异步任务,之前遇到过这个问题。我处理它的方法是在你的类中编写一个回调接口,扩展将在postExecute()上调用的AsyncTask。

public class MyDataGrabber extends AsyncTask<Void,Void,Void> {

    public interface Callback {
        public void onComplete(String data);
    }
    public Callback callBack;
    public MyDataGrabber(Callback callback) { // Initialize the callback
        this.callBack = callback;
    }
   // on preExecute
   // on doInBackground
   public void onPostExecute(String data){
        this.callBack.onComplete(data);
   }
}

// So when you call your async task it will look like this

Dialog dialog;
//.... set up and show dialog etc.

new MyDataGrabber(new MyDataGrabber.Callback(){
    @Override
    public void onComplete(String data){
        // Handle data
        doDataHandling();
        // Dismiss dialog
        if(dialog.isShowing){
            dialog.dismiss();
        }
    }
}).execute(String url...other data etc);
虽然关于AsyncTask的缺点,Salauyou是正确的,但是根据android api级别以及并发性问题执行并行或串行会有一些负面的副作用,即使在关闭之后,异步任务仍然在后台运行应用程序。通常,它需要您编写各种取消方法和弱引用才能正确处理。使用线程和处理程序绝对是一个有价值的解决方案。

答案 2 :(得分:0)

好吧所以我误解了这个问题....但是doinbackground不应该阻止任何事情,这就是为什么它在后台。

不,这就是答案....对话在ui上并非真实。只需从常规活动而不是异步任务中运行它。我喜欢这样使用你的男女同性恋,以及它美丽的

public class MainActivity extends Activity {
    private ProgressDialog dialog;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
         dialog = new ProgressDialog(this);
            dialog.setMessage("Downloading..");
            dialog.setIndeterminate(true);
            dialog.setCancelable(true);
            dialog.show();
        }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

}

基本上将对话框本身移出asynctask,并使用'this'作为上下文。如果您将访问权限从私人更改为公共

,那么从应用中的任何位置开始或终止它都没有问题