2010-11-13 7 views
2

Cher Android hackers, J'essaie de faire ce qui suit dans mon Android App: Lorsque l'utilisateur clique sur un élément de la liste dans un ListActivity, un ProgressDialog devrait apparaître, un préchargement devrait se produire et après il est fait, une autre activité devrait être appelée en utilisant une intention.Android: Problèmes avec ProgressDialog

J'ai essayé différentes approches. Ce qui ne fonctionnait pas du tout était l'utilisation d'une tâche asynchrone. Apparemment, je ne peux pas montrer, rejeter ou modifier mon ProgressDialog hors de la tâche asynchrone, si cette classe n'est pas un membre de mon activité originale.

je suis passé à un simple fil alors, est ce que je suis en train de le faire:

dialog = ProgressDialog.show(BookmarkActivity.this, "", "Loading...",true); 
new Thread() { 
    public void run() { 
     // do something 
     dialog.setMessage("Change Message..."); 
     // do more 
     dialog.dismiss(); 
     // ... 
     Intent intent = new Intent(BookmarkActivity.this, ThreadActivity.class); 
     BookmarkActivity.this.startActivity(intent); 
    } 
}.start(); 

Cela fonctionne presque, mais le changement du message de dialogue ne fonctionne pas. Je reçois des erreurs en disant quelque chose à propos de "fuites de fenêtres". (Je peux poster le journal complet si nécessaire).

Mes questions:

  • Comment puis-je utiliser un Async tâche pour cela, où la classe a son propre fichier?
  • Comment puis-je modifier le ProgressDialog de mon thread ou asyncTask sans provoquer une erreur pour modifier l'interface utilisateur dans un autre thread?

Merci à l'avance, Jan Oliver


Ok, avec l'aide de Jason, je mets ensemble cette Async tâche. Ça marche!

public class ThreadPreLoader extends AsyncTask<Object, String, Void> { 

    private Activity mActivity; 
    private ProgressDialog mDialog; 

    public ThreadPreLoader(Activity activity) { 
     mActivity = activity; 
    } 

    protected void onPreExecute() { 
     mDialog = new ProgressDialog(mActivity); 
     mDialog.setMessage("Loading..."); 
     mDialog.show(); 
    } 

    protected Void doInBackground(Object... args) { 
     publishProgress("Loading something else.."); 
     return null; 
    } 

    protected void onProgressUpdate(String... msg) { 
     mDialog.setMessage(msg[0]); 
    } 

    protected void onPostExecute(Void result) { 
     mDialog.dismiss(); 
    } 
} 

Merci encore, Jason.

Répondre

2

Vous devez utiliser un Async Task, Définir un Async Task personnalisé qui reçoit le contexte (this) de l'activité d'origine. Ensuite, gardez ce contexte pour plus tard Renvoyer la boîte de dialogue. De votre doInBackground() méthode, vous pouvez appeler postProgress(int progress) qui provoquera onProgressUpdate() à être appelé dans le async task, cette méthode est sur le thread d'interface utilisateur de sorte qu'il ne provoquera pas d'erreurs croisées. Une fois doInBackground() est terminée, la méthode onComplete() sera également appelée sur le thread d'interface utilisateur, c'est là que vous pouvez utiliser votre contexte enregistré et dissmiss la boîte de dialogue (context.dissmissDialog()

+0

Hey Jason, qui semble prometteur.Je vais essayer de mettre en œuvre cela et donner des commentaires plus tard! – janoliver

+0

J'ai mis à jour mon premier post avec une implémentation de votre idée. Cela ne fonctionne pas comme il se doit. Pourriez-vous regarder le code? – janoliver

+0

fonctionne maintenant, avait quelques bugs mineurs dans l'implémentation de AsynTask. Merci encore. – janoliver

2

Jetez un oeil à la classe d'Android Handler. Si vous créez le gestionnaire dans la méthode onCreate de votre activité, runnables qui sont envoyés à la méthode post du gestionnaire sont ensuite exécuté sur le thread d'interface utilisateur de votre activité:

Handler h; 
protected void onCreate(Bundle bundle) { 
    h = new Handler; 

    new Thread() { 
    public void run() { 
     // your run code 

     h.post(new Runnable() { /* change dialog here */ }); 
    } 
    }.start(); 

} 

Je ne suis pas sûr que ce soit la meilleure option, mais la peine d'essayer

+0

Hey Matthias, vous avez raison, je pourrais utiliser un gestionnaire et je suis en train d'essayer cela en ce moment. Mais une tâche asynchrone serait beaucoup plus utile. – janoliver

0

Dans AsyncTask
Vous devriez travaillez-vous qui ont besoin de temps en doInBackground et appelant l'intention comme les choses, que vous devez faire après cette tâche devrait être onPostExecute

public class ThreadPreLoader extends AsyncTask<Object, String, Void> { 

    private Activity mActivity; 
    private ProgressDialog mDialog; 

    public ThreadPreLoader(Activity activity) { 
     mActivity = activity; 
    } 

    protected void onPreExecute() { 
     mDialog = new ProgressDialog(mActivity); 
     mDialog.setMessage("Loading..."); 
     mDialog.show(); 
    } 

    protected Void doInBackground(Object... args) { 
     //do more 
     publishProgress("Loading something and reached somewhere.."); 
     //do more 
     publishProgress("Loading something and reached somewhere.."); 
     //do more 
     return null; 
    } 

    protected void onProgressUpdate(String msg) { 
     mDialog.setMessage(msg); 
    } 

    protected void onPostExecute() { 
     Intent intent = new Intent(BookmarkActivity.this, ThreadActivity.class); 
    BookmarkActivity.this.startActivity(intent); 

     mDialog.dismiss(); 
    } 
} 
Questions connexes