J'ai un thread distinct en cours d'exécution pour obtenir des données à partir d'Internet. Après cela, je voudrais mettre à jour le ListView dans le thread principal en appelant adapt.notifyDataSetChanged(). Mais ça ne marche pas. Une solution de contournement pour cela? Merci.Mettre à jour ListView dans le fil principal à partir d'un autre fil
Répondre
Utilisez AsyncTask (http://developer.android.com/reference/android/os/AsyncTask.html).
Invoke adapter.notifyDataSetChanged() dans onPostExecute (...) Méthode.
Pour plus de détails, s'il vous plaît lire ceci: http://android-developers.blogspot.com/2009/05/painless-threading.html
bons conseils Dans l'ensemble est http://android-developers.blogspot.com/2009/05/painless-threading.html
Personnellement, j'utiliser mon fil personnalisé (un fil d'extension de classe), mais envoyer une réponse au fil de l'interface utilisateur par un message. Ainsi, dans la fonction run() du thread, il y a:
Message msg;
msg = Message.obtain();
msg.what = MSG_IMG_SET;
mExtHandler.sendMessage(msg);
Le thread UI définit un gestionnaire de messages.
private Handler mImagesProgressHandler;
public void onCreate(Bundle bundle) {
mImagesProgressHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case LoadImagesThread.MSG_IMG_SET:
mArrayAdapter.setBitmapList(mImagesList);
mArrayAdapter.notifyDataSetChanged();
break;
case LoadImagesThread.MSG_ERROR:
break;
}
super.handleMessage(msg);
}
};
Ceci est réellement plus facile que AsyncTask.
Je préfère aussi cette méthode – Mark
J'ai oublié de mentionner: vous pouvez également ajouter un objet au message comme: msg.obj = someBitmap; et le recevoir dans le gestionnaire (qui peut par exemple mettre à jour un tableau ou une liste avec le bitmap reçu et notifier à l'adaptateur que les données sous-jacentes de la liste ont changé: mArrayAdapter.notifyDataSetChanged();). Dans ce cas, aucune condition de course ne peut se produire. – Yar
Attention - Voici des dragons! Cette classe Handler interne a une référence implicite à la classe externe 'this. Mieux vaut rendre ce Handler statique et prendre une Faible Référence à la classe extérieure. –
Ou, envoyer un message à la file d'attente de messages du listview (qui exécuter sur le thread d'interface utilisateur):
list.post(new Runnable() {
@Override
public void run() {
adapter.notifyDataSetChanged();
}
});
On suppose yourActivity
est l'activité que votre widget a été placé en elle, yourView
est la widget et adapter
est l'adaptateur du widget:
yourActivity.runOnUiThread(new Runnable() {
public void run() {
try{
adapter.notifyDataSetChanged();
}
catch{}
}
}
Vous pouvez utiliser une combinaison de RxJava et Retrofit à cet effet.
Voici comment vous pouvez le faire. Je vais utiliser l'API GitHub pour l'exemple.
Créez une interface Java pour votre API HTTP. L'utilisation de Observable permet de convertir la réponse en un flux.
public interface GitHubService {
@GET("users/{user}/repos")
Observable<List<Repo>> listRepos(@Path("user") String user);
}
Chaque événement étant une liste de repos.
Utilisez la classe Retrofit pour générer une implémentation de l'interface GitHubService. Vous pouvez ou ne pouvez pas fournir un client HTTP personnalisé.
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.client(okHttpClient) // OkHttp Client
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
GitHubService service = retrofit.create(GitHubService.class);
Maintenant vient la partie Rx. Vous devez ajouter un abonné pour écouter les réponses renvoyées par le serveur. En d'autres termes, réagissent à lui.
service.listRepos("octocat")
.subscribeOn(Schedulers.io()) // 1
.observeOn(AndroidSchedulers.mainThread()) // 2
.flatMap(Observable::from) // 3
.subscribe(repoList -> { // 4
// Update the list view
// notifyDataSetChanged
});
Voici ce que les lignes commentées avec des chiffres font -
1 - Il raconte l'OS qui se faufilent à utiliser pour effectuer l'appel. Nous choisissons le thread IO pour cela.
2 - Indique au système d'exploitation le thread à utiliser pour écouter la réponse. Nous faisons cela sur le thread principal, et mettre à jour l'interface utilisateur à la réception d'une réponse.
3 - Cette ligne démontre la vraie magie de Rx. Cette petite ligne simple convertit une liste de réponses en objets uniques. Par conséquent, nous réagirons à chaque objet au lieu de toute la liste. Vous pouvez en lire plus à ce sujet here.
4 - Cette ligne définit réellement le type de 'réaction' qui sera montré à l'événement. Vous pouvez mettre à jour l'adaptateur ici.
Un abonné plus complexe ressemble à ceci -
new Subscriber<Repo>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(Repo repo) {
}
}
post-scriptum - J'ai utilisé les lambdas dans les exemples ci-dessus. Vous pouvez ajouter cela par here.
L'astuce ici est la position où vous mettez les
mAdapter.notifyDataSetChanged();
Voici un exemple simple:
mRecyclerView = (RecyclerView) rootView.findViewById(R.id.recycler_view);
mAdapter = new myAdapter(......);
mAdapter.notifyDataSetChanged();
mRecyclerView.setAdapter(mAdapter);
ce travail pour moi parfaitement.
- 1. Comment mettre à jour des zones de texte dans le fil principal à partir d'un autre fil?
- 2. Appelez le fil principal du fil secondaire dans Android
- 3. Mettre à jour JFrame avec le fil? - Java
- 4. Comment tuer le fil principal?
- 5. Exception dans le fil "principal" java.lang.ClassCastException:
- 6. Fil Java, accès à l'objet dans le code principal
- 7. Fil de la fenêtre VTK à partir du fil principal, C++
- 8. Java: Exception dans le fil principal java.lang.NoClassDefFoundError
- 9. Mise à jour de midlet sans fil
- 10. terminer un fil secondaire du fil principal (cacao)
- 11. Comment activer une minuterie à partir d'un autre fil/classe
- 12. Trouver le fil de premier plan à partir du fil d'arrière-plan
- 13. mise à jour Silverlight fil croix question
- 14. Comment attendre le fil de travail dans le formulaire principal?
- 15. Surveillance du fil asp.net à partir d'une autre page
- 16. Cacher/Montrer Winforms GUI C# à partir d'un autre fil
- 17. Créer un contrôle utilisateur à partir d'un autre fil
- 18. Synchroniser le sous-fil avec le fil principal - problème pas si évident
- 19. Mettre à jour la zone de texte de la classe dans un fil différent
- 20. Fil d'arrière-plan dans .NET
- 21. Exception dans le fil "principal" java.lang.OutOfMemoryError, Comment trouver et résoudre?
- 22. tuer l'activité dans le fil
- 23. Envoyer les données mises à jour au fil d'arrière-plan
- 24. Mise à jour du modèle GEF à partir d'un fil d'arrière-plan
- 25. Est-ce que QWebView/QWebPage télécharge le contenu dans un fil séparé ou dans le fil principal/gui?
- 26. Ajout d'éléments de menu à partir d'un fil distinct
- 27. LowLevelMouseProc dans le fil d'arrière-plan
- 28. comment mettre à jour l'affichage dans le thread d'interface utilisateur à partir du thread de travail
- 29. .NET: Comment avoir des données de fil principal de signal de fil de fond est disponible?
- 30. iphone - le fil principal gèle pendant une demi-seconde ... pourquoi?
http://stackoverflow.com/a/33584826/1318946 –