2014-03-26 117 views
1

我一直在试图让数据被检索时进度对话框工作。AsyncTask progressdialog不显示,doInBackground阻止UI

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

到目前为止,它没有显示任何进度条,因为我认为funcion fillMyTickets阻塞UI线程,因此对话框不显示。我不明白如何解决这个问题。通过阅读Stackoverflow,我发现了解决方案,比如在AsyncTask中使用onProgressUpdate函数,但那不是我想要的。我需要的是一个等待的对话框,表示在HTTP呼叫结束时下载并消失。

的AsyncTask功能exampleFragment.java

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

而且在评论dialog.dismiss() onPostExecute的AsyncTask时对话框不显示,但然后ofcourse永远不会关闭。

+1

你能展示你如何执行任务吗? – codeMagic

+0

确保你在UI线程上调用'new PrefetchData()。execute()'(也许在你的''onClick''处理程序中,然后你应该拥有你想要的。) – kiruwka

+0

它必须自动加载。 – Niels

回答

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

希望它有帮助!

+0

doInBackground(Void ... arg0)出现错误,'此方法必须返回类型为空的结果' – Niels

+0

我更新了我的答案,现在就试试。 – Giacomoni

0

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

没有那个答案....对话不是在UI上进行的。只需从常规活动而不是异步任务中运行即可。我jused使用乌尔男女同校的这个样子,和美丽的

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

} 

所以basicly移动对话框本身出的AsyncTask,并使用“这个”作为背景。你可以从你的应用程序的任何地方启动或杀死它,如果你将访问权限从私有公开改为公开,你将没有任何问题

+0

我不是想为了使飞溅屏幕工作,我只使用了指南的最后部分,我试图显示一个对话框,当票据被下载并被放入一个列表视图中时,当使用上面的代码时,对话框也不会显示。这就是为什么我认为用户界面被阻止,因为在doInBackground之前和之后正在打开和关闭对话框。 – Niels

+0

''在'UI线程'上显示'Dialog' * *,因为它在'onPreExecute()'中显示, *运行在UI线程上 – codeMagic

+0

是的,但是id dosnt必须严格地说...我不是bieng争论性的......只是说你可以通过在异步中保留获取来实现你想要的,并将对话移动到主要活动你认为它是一个花式吐司,你不需要对话的异步任务 – La5t5tarfighter

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

Salauyou是正确的,虽然有关的AsyncTask的缺点,也有一些负面影响与它并行或串行取决于Android的API级别,以及并发性问题和异步任务是仍然在后台运行的执行,甚至关闭应用程序后。通常需要编写各种取消方法和弱引用才能正确处理。使用线程和处理程序绝对是一个有价值的解决方案。

+0

此外,许多进度对话框可以通过setSupportProgressBarIndeterminateVisibility(false | true)// appcompat version | setProgressBarIndeterminateVisibility(假|真) –

相关问题