2010-04-24 4 views
1

J'essaie d'afficher un ProgressDialog indéfini, alors qu'une AsyncTask se lie à un RemoteService. RemoteService crée une liste des contacts des utilisateurs lors de la création du service. Pour une longue liste de contacts cela peut prendre 5 ~ 10 secondes.ProgressDialog ne s'affiche pas avant la fin de la tâche AsyncTask

Le problème que j'ai, c'est que le ProgressDialog ne s'affiche pas avant que RemoteService ait construit sa liste de contacts. J'ai même essayé de mettre un Thread.sleep pour donner le temps à ProgressDialog d'apparaître. Avec l'instruction sleep, ProgressDialog se charge et commence à tourner, mais se bloque dès que RemoteService commence à faire son travail.

Si je viens de transformer le AsyncTask en code fictif, et que je le laisse simplement dormir pendant un moment, tout fonctionne correctement. Mais quand la tâche doit faire un travail réel, c'est comme si l'interface se trouvait juste et attend.

Des idées sur ce que je fais mal?

@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: Ajouté 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

Où est le code de onCreateDialog()? – Matthias

+0

Matthias, j'ai ajouté le onCreateDialog – tedwards

Répondre

0

NE PAS faire un bindService() de doInBackground(). Tout d'abord, il est presque instantané, de sorte que vous n'avez pas besoin de l'avoir dans un fil de fond - tout ce que vous faites est de perdre du temps CPU et de la batterie. Deuxièmement, il doit travailler avec le Looper et la file d'attente des messages pour votre Context, et ainsi de le mettre dans un fil de fond est dangereux à mon humble avis.

Notez également que vous êtes lié au service et au service. Il y a quelques cas où cela est approprié, mais normalement, vous n'avez besoin que de l'un ou de l'autre.

+0

C'est la chose, ce n'est pas instantané. J'ai besoin du service pour construire et conserver une liste des contacts des utilisateurs. J'ai donc le service de construction des contacts dans onCreate. Ensuite, après que je suis lié à lui, je récupère les contacts du service et les affiche. Je ne pensais pas qu'il y aurait des problèmes de concurrence puisque l'AsyncTask se ferme après la liaison au RemoteService. Peut-être qu'il y a, et il bloque le fil de l'interface utilisateur? J'ai lié et commencé le service parce que je prévois d'avoir plusieurs applications lier au service. Est-ce que ce n'est pas approprié? – tedwards

+0

"J'ai donc le service de construction des contacts dans onCreate." Déplacez * that * logic dans une AsyncTask dans le service, car 'onCreate()' est appelé sur le thread d'application principal, quel que soit l'endroit où vous essayez de vous lier. – CommonsWare

+0

J'ai aussi essayé quelque chose comme ça, mais j'ai rencontré le problème de devoir attendre que le contact produisant le thread se joigne avant que je puisse retourner le résultat de l'appel pour les consommer fait par RemoteServiceConnection. On dirait que j'ai besoin de comprendre comment transmettre un message au thread d'interface utilisateur pour qu'il sache quand les contacts sont prêts à être consommés. Merci pour votre aide! Au fait, j'envisageais d'acheter vos livres. Cela a scellé l'affaire (bien que et payday quand il vient autour). – tedwards

Questions connexes