简体   繁体   English

未显示AsyncTask进度对话框,doInBackground阻止了UI

[英]AsyncTask progressdialog not showing, doInBackground blocks UI

I've been trying to get a progressdialog working while the data is being retrieved. 我一直在尝试在检索数据时使progressdialog工作。

I used this link Implement android splash screen while loading data to get me started but it seems I cannot get it to work properly. 在加载数据时使用了此链接实现android启动画面,但我似乎无法正常工作。

So far it does not show any progressbar because I think the funcion fillMyTickets blocks the UI thread and therefor the dialog is not shown. 到目前为止,它没有显示任何进度条,因为我认为funcion fillMyTickets会阻止UI线程,因此不会显示该对话框。 I do not understand how to resolve this problem. 我不明白如何解决此问题。 By reading through Stackoverflow I found solutions such as use onProgressUpdate function in AsyncTask but that's not what I want. 通过阅读Stackoverflow,我找到了解决方案,例如在AsyncTask中使用onProgressUpdate函数,但这不是我想要的。 All I need is a waiting dialog that says downloading and dissapears when the HTTP call is over. 我需要的是一个等待对话框,其中显示HTTP通话结束后下载并消失。

Asynctask function in exampleFragment.java 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 function in exampleFragment.java exampleFragment.java中的 fillMyTickets函数

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(Activity activity) function where AsyncTask is executed 执行AsyncTask的onAttach(活动活动)函数

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

Also when commenting dialog.dismiss() in onPostExecute of AsyncTask the dialog does show but then ofcourse never closes. 同样,在AsyncTask的onPostExecute中注释dialog.dismiss()时,该对话框确实显示,但随后永远不会关闭。

You are calling a method that register a listener and download some data, but before the downloading the data, you are returning from the doInBackground and dismissing the dialog, so your dialog is being shown and the hidden. 您正在调用注册侦听器并下载一些数据的方法,但是在下载数据之前,您是从doInBackground返回并关闭该对话框,因此您的对话框被显示并隐藏。 Try to modify your code and dismiss the dialog just when it completes the download: 尝试修改代码,并在完成下载后关闭对话框:

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);
}

Hope it helps! 希望能帮助到你!

While I would recommend that you use the Volley library for doing async network requests(has retry policy, thread pool executor stuff baked in, and some other tasty stuff that you can extend and modify), in past projects I've used an async task with a progress dialog and have run into this exact issue before. 虽然我建议您使用Volley库执行异步网络请求(具有重试策略,引入线程池执行程序的东西,以及一些可以扩展和修改的其他好东西),但在过去的项目中,我使用了异步任务与进度对话框,并且之前已经遇到了这个确切的问题。 The way I've handled it was to write a callback interface into your class that is extending AsyncTask that will be called on postExecute(). 我处理它的方法是在您的类中编写一个回调接口,该接口扩展了将在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);

Salauyou is correct though about the drawbacks of AsyncTask, there are some negative side effects with it executing in parallel or serial depending on android api level as well as concurrency issue and async tasks being still running in the background even after you close the app. Salauyou是正确的,尽管它关于AsyncTask的缺点,但它有一些负面影响,取决于android api的级别,它以并行或串行方式执行,并且即使关闭应用程序,并发问题和异步任务仍在后台运行。 Often times it requires that you write all sorts of canceling methods and weak references to handle correctly. 通常,它需要您编写各种取消方法和弱引用才能正确处理。 Using a thread and handler is definitely a worthwhile solution to this as well. 使用线程和处理程序绝对是一个值得解决的方案。

ok so i misread this question.... but doinbackground shouldnt block anything thats why its in the background. 好的,所以我误读了这个问题。...但是doinbackground不应该阻止任何东西,这就是为什么它在后台。

no that is the answer.... dialog isnt acutally on the ui. 不,这就是答案。...ui上不是对话框。 just run it from your regular activty instead of async task. 只需从常规活动运行它即可,而不是异步任务。 i jused used ur coed like this, and its beautiful 我认为你这样使用过男女同校

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;
    }

}

so basicly move the dialog itself out of asynctask, and use 'this' as context. 因此从根本上将对话框本身移出asynctask,并使用“ this”作为上下文。 youll have no problem starting or killing it from anywhere in your app if you change the access from private to public 如果您将访问权限从私人更改为公共,则可以从应用程序中的任何位置启动或杀死它

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM