ProgressDialog直到AsyncTask完成后才显示

ProgressDialog直到AsyncTask完成后才显示

问题描述:

我试图显示一个不确定的ProgressDialog,而AsyncTask绑定到RemoteService。当服务第一次创建时,RemoteService会建立用户联系人列表。对于一长串联系人,这可能需要5到10秒。ProgressDialog直到AsyncTask完成后才显示

我遇到的问题是ProgressDialog在RemoteService建立它的联系人列表之后才显示。我甚至尝试过放入Thread.sleep来让ProgressDialog时间显示出来。通过sleep语句,ProgressDialog加载并开始旋转,但只要RemoteService开始工作就会锁定。

如果我只是把AsyncTask变成虚拟代码,让它休眠一段时间,一切正常。但是,当任务需要做实际工作时,就像UI刚刚坐下来等待。

关于我在做什么错误的任何想法?

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    Log.d(IM,"Start Me UP!!"); 
    setContentView(R.layout.main); 
    Log.d(IM, "Building List View for Contacts"); 
    restoreMe(); 
    if (myContacts==null){ 
     myContacts = new ArrayList<Contact>(); 
     this.contactAdapter = new ContactAdapter(this, 
                R.layout.contactlist, 
                myContacts); 
     setListAdapter(this.contactAdapter); 
     new BindAsync().execute(); 
    } 
    else{ 
     this.contactAdapter = new ContactAdapter(this, 
                R.layout.contactlist, 
                myContacts); 
     setListAdapter(this.contactAdapter); 

    } 
} 

private class BindAsync extends AsyncTask<Void, Void, RemoteServiceConnection>{ 
    @Override 
    protected void onPreExecute(){ 
     super.onPreExecute(); 
     Log.d(IM,"Showing Dialog"); 
     showDialog(DIALOG_CONTACTS); 
    } 
    @Override 
    protected RemoteServiceConnection doInBackground(Void... v) { 
     Log.d(IM,"Binding to service in BindAsync"); 
     try{ 
     Thread.sleep(2000); 
     } catch (InterruptedException e){ 

     } 

     RemoteServiceConnection myCon; 
     myCon = new RemoteServiceConnection(); 
     Intent i = new Intent(imandroid.this,MyRemoteService.class); 
     bindService(i, myCon, Context.BIND_AUTO_CREATE); 
     startService(i); 
     Log.d(IM,"Bound to remote service"); 
     return myCon; 
    } 
    @Override 
    protected void onPostExecute(RemoteServiceConnection newConn){ 
     super.onPostExecute(newConn); 
     Log.d(IM,"Storing remote connection"); 
     conn=newConn; 
    } 

}; 

编辑:添加onCreateDialog

protected Dialog onCreateDialog(int id){ 
    switch(id){ 
    case DIALOG_CONTACTS: 
     ProgressDialog progDialog = new ProgressDialog(imandroid.this); 
     progDialog.setMessage("Loading Contacts... Please Wait"); 
     progDialog.setCancelable(false); 
     return progDialog; 
    default: 
     return super.onCreateDialog(id); 
    } 
} 
+1

onCreateDialog()的代码在哪里? – Matthias 2010-04-24 08:59:24

+0

Matthias,我添加了onCreateDialog – tedwards 2010-04-24 16:33:50

不要从doInBackground()bindService()。首先,它几乎是瞬间的,所以你不需要在后台线程中使用它 - 你所做的只是浪费CPU时间和电池。其次,它需要与Looper和消息队列Context,因此把它放在后台线程是危险的恕我直言。

另请注意,您都绑定到服务并启动服务。有几种情况适用,但通常您只需要一种或另一种。

+0

这就是事情,它不是瞬时的。我需要该服务来构建并保留用户联系人列表。所以我有服务在onCreate中建立联系人。然后,我绑定它后,我从服务中获取联系人并显示它们。 我不认为会有任何并发​​问题,因为AsyncTask绑定到RemoteService后退出。也许有,并阻止了UI线程? 我绑定并启动服务,因为我计划让多个应用程序绑定到该服务。这不合适吗? – tedwards 2010-04-24 16:55:03

+0

“所以我有服务建立它的onCreate中的联系人。”将* that *逻辑移入服务中的AsyncTask,因为在主应用程序线程上调用onCreate(),无论您尝试绑定到哪个位置。 – CommonsWare 2010-04-24 17:18:05

+0

我也尝试过类似的方法,但是我遇到了必须等待联系生成线程加入的问题,然后才能将调用的结果返回给RemoteServiceConnection所使用的线程。 听起来就像我需要弄清楚如何将消息传递回UI线程,让它知道联系人何时可以使用。 感谢您的帮助! 顺便说一下,我正在考虑购买你的书。这笔交易的签署(以及发生的时间)。 – tedwards 2010-04-24 17:47:54