当AsyncTask.get()调用时,ProgressDialog不显示
可能重复:
AsyncTask阻止用户界面威胁,并显示进度条延迟
我想从任何服务器检索JSON时显示progressDialog。 所以我使用AsyncTask作为解决scheme(不确定任何不同的出路)。
一切都很好,ProgressDialog正常工作,直到我使用AsyncTask实例调用.get()方法。 我想这是阻止用户界面。 这是我的AsyncTask:
public class myAsync extends AsyncTask<String, String, List> { String message; // for dialog message ProgressDialog progress; Intent myIntent; Context ctx; public myAsync(String message, Context ctx) { this.message = message; this.ctx = ctx; progress = new ProgressDialog(ctx); } @Override protected void onPreExecute() { progress.setMessage(message); progress.setIndeterminate(true); progress.setCancelable(false); progress.show(); } @Override protected List doInBackground(String... params) { //returns any list after the task return anyList; } @Override protected void onPostExecute(List result) { if(progress.isShowing()) progress.dismiss(); } }
这里是myActivity这是调用AsyncTask:
myAsync asyncTask = new myAsync("Loading...", this); asyncTask.execute("Any string", "Other string"); asyncTask.get(); // If I comment out this line, ProgressDialog works
执行后,当我试图从doInBackground和onPostExecute都logging结果都没有问题。 但是,如果我想用.get()得到结果ProgressDialog没有显示或显示很less的时间(可能是0.2秒)
有什么问题?
是的, get()
在必要时等待计算完成,然后检索其结果。 这意味着,你正在阻塞你的UI线程,等待结果。
解决scheme:不要打电话get
通常,你将在postExecute
调用一个函数(callback函数)。
调用.get()
会将AsyncTask
更改为有效的“ SyncTask
”,因为它会导致当前线程(这将是UI线程)等待AsyncTask
完成其处理。 由于您现在阻止了UI线程,因此对ProgressDialog
的.show()
方法的调用永远不会有机会让对话框自行绘制屏幕。
删除电话将允许它在后台正常运行。
如果你需要在任务完成后进行处理,我build议你把它放在onPostExecute
方法本身中,或者使用onPostExecute
对Activity
的callback。
如果我正确理解你的问题,你需要在ProgressDialog
更新AsyncTask的ProgressDialog
,目前这个function还没有工作。 所以有几件事要注意:我不知道你想用.get()
实现什么,但是我假设你想显示进度。
我已经修改了下面的程序,用你的AsyncTask的进度来更新UI线程。 每次您需要更新进度时,请在doInBackground
方法中更新该prog
variables。
public class myAsync extends AsyncTask<String, Integer, List> { String message; // for dialog message ProgressDialog progress; Intent myIntent; Context ctx; public myAsync(String message, Context ctx) { this.message = message; this.ctx = ctx; progress = new ProgressDialog(ctx); } @Override protected void onPreExecute() { // Runs on the UI thread progress.setMessage(message); progress.setIndeterminate(true); progress.setCancelable(false); progress.show(); } @Override protected List doInBackground(String... params) { // Runs in the background thread // publish your progress here!! int prog = 5; // This number will represent your "progress" publishProgress(prog); return anyList; } protected void onProgressUpdate(Integer... progress) { // Runs in the UI thread // This method will fire (on the UI thread) EVERYTIME publishProgress // is called. Log.d(TAG, "Progress is: " +progress); } @Override protected void onPostExecute(List result) { // Runs in the UI thread for (int i=0; i<result.size(); i++) { Log.d(TAG, "List item: " + result.get(i)); } if(progress.isShowing()) progress.dismiss(); } }
尝试使用runOnUiThread像这样:
runOnUiThread(new Runnable(){ public void run() { dialog.show(); }});
在AsyncTask上运行的东西意味着它从UIthread运行,所以通常你不能在asynchronous方法里面运行ui操作,而没有处理器和我通常不用的东西。 我也通过创build一个progressDialog作为我的类上面的一个variables来处理这样的解决scheme,因此它对整个类都是可见的。 然后我在asynctask之前调用progressdialog,然后由于它对整个类的可见性,我在onPostExecute中调用.dissmiss()