Android: Comment puis-je faire une liste à jour périodiquement?
Je n'ai jamais eu ce travail de façon simple. Désolé si je suis un peu vague. Je vais essayer de donner des précisions sur ce que je suis en train de faire. Je suis en train de construire une listview qui saisit ses données à partir d'un webservice. Une fois que j'initialise une listview, je veux garder l'interrogation du serveur web régulièrement et de mettre à jour le contenu de la liste. Pour cela, je suis en train de faire quelque chose comme ceci:
public class SampleAutoUpdateList extends Activity {
//Autoupdate handler
private Handler handler = new Handler();
private Runnable updater = new Runnable() {
public void run() {
/*
* Update the list
*/
try {
Log.i("UPDATE", "Handler called");
searchAdapter = getFeed(URL);
searchAdapter.notifyDataSetChanged();
handler.postDelayed(this, Configuration.REFRESH_INTERVAL);
} catch(Exception e) {
Log.e("UPDATE ERROR", e.getMessage());
}
}
};
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.linearmode);
this.context = this;
searchAdapter = getFeed(URL);
LinearLayout l2 = (LinearLayout) findViewById(R.id.secondaryLayout);
ListView list = new ListView(context);
l2.addView(list);
//display UI
UpdateDisplay(list);
updater.run();
}
private SearchAdapter getFeed(String URL) {
try
{
SearchHandler handler = new SearchHandler();
URL url = new URL(URL);
String data = convertStreamToString(url.openStream());
data = data.substring(data.indexOf('['), data.length()-1);
handler.parseJSON(data);
return handler.getFeed();
}
catch (Exception ee)
{
//if we have a problem, simply return null
Log.e("getFeed", ee.getMessage());
return null;
}
}
private void UpdateDisplay(View searchView) {
//TODO Auto-generated method stub
//TODO Auto-generated method stub
searchList = (ListView) searchView;
myProgressDialog = ProgressDialog.show(this,
"Please wait...", "Loading search....", true);
new Thread() {
public void run() {
try{
Thread.sleep(2000);
} catch (Exception e) { }
runOnUiThread(new Runnable() {
@Override
public void run() {
if (searchAdapter == null)
{
Log.e("ERROR", "No Feed Available");
return;
}
searchAdapter.setContext(context);
searchList.setAdapter(searchAdapter);
searchList.setSelection(0);
}
});
//Dismiss the Dialog
myProgressDialog.dismiss();
}
}.start();
}
}
Et la SearchHandler classe est simple:
public class SearchHandler extends DefaultHandler {
SearchAdapter _adapter;
SearchItem _item;
public SearchHandler()
{
}
public SearchAdapter getFeed()
{
return _adapter;
}
public void parseJSON(String data) {
//TODO Auto-generated method stub
_adapter = new SearchAdapter();
JSONArray parseArray;
try {
parseArray = new JSONArray(data);
for (int i=0; i < parseArray.length(); i++) {
SearchItem item = new SearchItem();
JSONObject jsonUser = parseArray.getJSONObject(i);
item.set_from(jsonUser.getString ("from"));
item.set_msg(jsonUser.getString("msg"));
}
} catch (JSONException e) {
//TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Peu importe ce que je fais, le gestionnaire est appelé et les nouveaux éléments sont récupérés, mais la liste n'est jamais actualisée... Toutes les idées sur ce qui pourrait mal se passer?
Désolé... Juste mis à jour à ma question...
OriginalL'auteur Legend | 2010-02-04
Vous devez vous connecter pour publier un commentaire.
Bien, c'est un peu difficile à suivre votre code, puisque vous n'avez qu'un fragment, et quelques-uns des très pertinentes bits. Par exemple, en fonction de votre code, votre liste devrait être éternellement vides, puisque vous n'avez jamais associer le
searchAdapter
avec unListView
...au moins dans le code que vous avez montré.Cela étant dit, les lignes suivantes semblent particulièrement étrange:
Je vais supposer que
getFeed()
(non illustré) crée un nouveauListAdapter
de quelque sorte. SigetFeed()
est la création d'une nouvelleListAdapter
, il n'est pas nécessaire d'appelernotifyDataSetChanged()
sur elle, comme son jeu de données n'a pas changé -- c'est tout nouveau. En outre, sauf si vous fréquentez ce nouveauListAdapter
à votreListView
, la nouvelleListAdapter
n'aura aucun effet.Si je suis aboiements le mauvais arbre, envisager d'ajouter des lignes à votre exemple montrant la mise en œuvre de
getFeed()
et où vous utilisezsearchAdapter
.OK, bon, alors, je pense que ma réponse est exacte. Votre SearchHandler crée de nouvelles cartes à chaque fois. Cependant, je ne vois que vous qui associe la carte avec la liste une fois, dans UpdateDisplay(). Par conséquent, la deuxième et les suivantes cartes sont juste créé et mis au rebut, près que je peux dire.
Hmm.. Pour une raison quelconque, je n'ai jamais attendu de ce problème. Donc, dois-je ré-associer à la liste, à chaque fois, ou proposez-vous une autre méthode?
Eh bien, il y a deux approches. Tout d'abord, vous pourriez mettre à jour votre SearchAdapter en place, à l'aide de notifyDataSetChanged() pour déclencher la liste mise à jour. Depuis, je ne pense pas que vous avez le SearchAdapter code posté, je ne sais pas si ce sera facile ou difficile. Deuxièmement, vous pouvez l'appeler setAdapter() sur la liste chaque fois que vous créez un nouvel adaptateur.
Le second semblait le plus facile d'essayer d'abord j'ai donc fait la liste "liste" dans une déclaration globale et essayé d'y accéder depuis le gestionnaire de liste.setAdapter(searchAdapter); et il ne cesse de jeter un NullPointerException à android.widget de.ListView.measureScrapChild(ListView.java). Je suis en train de voir quel est le problème ici... Va revenir bientôt, si ça marche...
OriginalL'auteur CommonsWare