问题
I am trying to display an indefinite ProgressDialog, while an AsyncTask binds to a RemoteService. The RemoteService builds a list of the users contacts when the service is first created. For a long list of contacts this may take 5~10 seconds.
The problem I am having, is that the ProgressDialog does not display until after the RemoteService has built it's list of contacts. I even tried putting a Thread.sleep in to give the ProgressDialog time to show up. With the sleep statement the ProgressDialog loads and starts spinning, but then locks up as soon as the RemoteService starts doing it's work.
If I just turn the AsyncTask into dummy code, and just let it sleep for a while, everything works fine. But when the task has to do actual work, it is like the UI just sits and waits.
Any ideas on what Im doing wrong ?
@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;
}
};
EDIT: Added 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:
Do NOT do a bindService()
from doInBackground()
. First, it is nearly instantaneous, so you do not need to have it in a background thread -- all you are doing is wasting CPU time and battery. Second, it needs to work with the Looper
and message queue for your Context
, and so putting it in a background thread is dangerous IMHO.
Also note that you are both binding to the service and starting the service. There are a few cases where that is appropriate, but normally you only need one or the other.
来源:https://stackoverflow.com/questions/2703833/progressdialog-does-not-display-until-after-asynctask-completes