Temporizador de vista de lista de Android ejecutar en cada segundo
Tengo un problema con el uso de un temporizador en un listview
. En el elemento de lista que mostré usando los valores sqlite. Hay una vista de textview
que muestra la diferencia de tiempo de la última hora actualizada de los datos y la hora actual. tengo que mostrarlo en cada segundo. por lo que el usuario puede saber cuánto tiempo ha actualizado el registro.
He intentado esto de varias maneras.
Primera manera
Intenté agregar temporizador en la clase del adapter
. así que para cada artículo nuevo temporizador se crea. así que la aplicación se estrelló debido a muchos temporizadores ejecutados simultáneamente.
Segundo camino
Intenté usar la manera de adapter.notifyDataSetChanged (). Como esto.
Handler timerHandler = new Handler(); Runnable timerRunnable = new Runnable() { @Override public void run() { if (adapterChatThread != null) { adapter.notifyDataSetChanged(); } timerHandler.postDelayed(this, 1000); // run every second } }; timerRunnable.run();
Me muevo a otra actividad cuando haga clic en el elemento de la lista y el usuario puede volver a esta Activity
.
así que en Onresume he usado
timerHandler.postDelayed(timerRunnable, 500);
y OnPause
timerHandler.removeCallbacks(timerRunnable);
El problema es que los datos no se muestran bien. Quiero decir que en cada segundo la diferencia de datos no es un segundo. algún tiempo differnce es 2sec, 5 seg, .. etc
significa que el temporizador no funciona como esperaba.
Tercera vía
Usé un asynctask y lo llamo en cada segundo usando un temporizador.
class ThreadTimer extends AsyncTask<Void, Void, Void> { @Override protected Void doInBackground(Void... params) { return null; } @Override protected void onPostExecute(Void result) { if (adapter != null) adapter.notifyDataSetChanged(); super.onPostExecute(result); } }
Lo llamé como aquí
Handler timerHandler = new Handler(); Runnable timerRunnable = new Runnable() { @Override public void run() { new ThreadTimer().execute(); timerHandler.postDelayed(this, 1000); // run every second } }; timerRunnable.run();
tema anterior desencadenado. (los datos no se muestran bien)
Cuarto camino
Utilizar AsyncTask
como este
class ThreadTimer extends AsyncTask<Void, Void, Void> { void Sleep(int ms) { try { Thread.sleep(ms); } catch (Exception e) { } } @Override protected Void doInBackground(Void... params) { while (threadRun) { Sleep(1000); return null; } return null; } @Override protected void onPostExecute(Void result) { adapter.notifyDataSetChanged(); super.onPostExecute(result); } }
Llamé a esta clase en OnResume. En pausa establezco threadRun = false;
la cuestión es la misma.
por favor, ayúdame.
Mi requisito es actualizar el elemento de la lista en cada segundo.
Gracias.
editar
aquí está mi código de actualización textview de la clase adaptador.
Date lastUpdatedTime; final ChatThreadDAO ctd = new ChatThreadDAO(); long timeForNextResponse = ctd.getLastRespondedTime(vct.get(position).getThread_id()); try { if (vct.get(position).getThread_read_status() == 1 && timeForNextResponse > 0) { final long respTime = timeForNextResponse; SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); lastUpdatedTime = formatter.parse(vct.get(position).getLast_updated_time()); final long timeDiff = (new Date()).getTime() - lastUpdatedTime.getTime(); if (timeDiff <= respTime) { timeForNextResponse = respTime - timeDiff; ctd.updateTimeRespondToLastMsg(vct.get(position).getThread_id(), timeForNextResponse); holder.tvChatTimer.setVisibility(View.VISIBLE); holder.tvChatTimer.setText(timeForNextResponse / 1000 + ""); } else { ctd.updateTimeRespondToLastMsg(vct.get(position).getThread_id(), 0); } } else { holder.tvChatTimer.setVisibility(View.INVISIBLE); } } catch (ParseException e) { e.printStackTrace(); }
aquí vct es
Vector vct;
Asigno los valores al vector en el constructor de clase de adaptador.
Aquí hay un ejemplo similar a su caso.
private class connectionControl extends Thread { boolean stop_ = false; public void stop_() { this.stop_ = true; } public void run() { System.out.println("Thread started:" + getClass().getSimpleName()); while(!this.stop_) { try { Thread.sleep(1000); runOnUiThread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub Calendar c = Calendar.getInstance(); int rightNow = c.get(Calendar.SECOND) + c.get(Calendar.MINUTE)*60; if(rightNow - lastUpdatedTime > 10) { wirelessIcon.setImageResource(R.drawable.wirelessred); } else if(rightNow - lastUpdatedTime > 5) { wirelessIcon.setImageResource(R.drawable.wirelessyellow); } else { wirelessIcon.setImageResource(R.drawable.wirelessgreen); } } }); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } System.out.println("Thread stoped:" + getClass().getSimpleName()); } }
Configuró su lastUpdatedTime de la misma manera que creó rightNow cada vez que llama al método notifyDataSetChanged () de su adaptador.