Android listview 计时器每秒运行一次
Posted
技术标签:
【中文标题】Android listview 计时器每秒运行一次【英文标题】:Android listview timer run in every second 【发布时间】:2014-04-24 01:44:30 【问题描述】:我在 listview
上使用计时器时遇到问题。
在我使用 sqlite 值显示的列表项中。有一个textview
显示数据的最后更新时间和当前时间的时间差。我必须每一秒都显示出来。这样用户就可以知道他更新了多长时间。
我尝试了多种方式。
第一种方式
我尝试在adapter
类中添加计时器。所以为每个项目创建新的计时器。所以应用程序崩溃了,因为许多计时器同时运行。
第二种方式
我尝试使用 adapter.notifyDataSetChanged() 方式。像这样。
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();
当点击列表项时,我移动到另一个活动,用户可以回到这个Activity
。
所以在 Onresume 中我使用了
timerHandler.postDelayed(timerRunnable, 500);
和 OnPause
timerHandler.removeCallbacks(timerRunnable);
问题是数据显示不佳。我的意思是每一秒的数据差异不是一秒。一些时间差是 2 秒、5 秒、.. 等等。
表示计时器没有按预期工作。
第三条路
我使用了一个异步任务,并使用计时器每秒调用它。
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);
我在这里这样称呼它
Handler timerHandler = new Handler();
Runnable timerRunnable = new Runnable()
@Override
public void run()
new ThreadTimer().execute();
timerHandler.postDelayed(this, 1000); // run every second
;
timerRunnable.run();
上一个问题已触发。 (数据显示不好)
第四条路
这样使用AsyncTask
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);
我在 OnResume 中调用了这个类。 在暂停时我设置 threadRun= false;
问题是一样的。
请帮帮我。
我的要求是每秒更新列表项。
谢谢。
编辑
这是我的适配器类 textview 更新代码。
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();
这里是 vct
矢量vct;
我将值分配给适配器类构造函数中的向量。
【问题讨论】:
等等,你是在修改适配器中的数据吗? lastUpdatedTime 必须在您的适配器之外设置,适配器用于处理您的每一行,因此即使它可能工作,您仍然会在每次创建或修改列表视图的一行时设置您的 lastUpdatedTime。每当您更改矢量的内容或通知适配器刷新时,都必须设置 lastUpdatedTime。 非常感谢您。我删除了适配器类中的更新 lastUpdatedTime,它现在可以正常工作了。非常感谢。 当我不滚动它时它起作用了。但是当滚动列表时它显示不正确的值。还有其他方法可以实现吗? 好吧,我无法用您当前的代码来判断,但请记住,您的行是在 GetView() 方法上创建/修改的。因此,您需要在此处进行一些修改,否则您的数组中的数据可能不正确。您可以检查您的数组是否包含正确的值。每次您根据数组滚动时,默认自定义适配器都会创建一行,但大多数时候您会修改它,以便它重新使用自己。但无论哪种方式,您的 get 视图都会调用。 【参考方案1】:这是一个与您的情况类似的示例。
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.wireles-s-red);
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());
每当您调用适配器的 notifyDataSetChanged() 方法时,您设置 lastUpdatedTime 的方式与您创建 rightNow 的方式相同。
【讨论】:
我建议您使用处理程序来刷新列表视图,因为处理程序正在处理您的 UI 线程。 我把这段代码放在哪里。请看我的编辑帖子。我添加了我的适配器类代码。谢谢。 这是一个线程类来检查你的更新时间。 run() 中的 if 条件是您检查经过时间的条件。您可以更改代码块。您可以将其放在单独的文件中,也可以作为 Activity、片段或您正在使用的任何内容的内部类。您在开始活动时创建一个对象,并在刷新列表的任何位置更改 lastUpdatedTime。编辑:刚刚意识到我将其用作内部类,因为 lastUpdatedTime 是我的超类的变量。如果你把它放在一个单独的文件中,你需要为你的 lastUpdatedTime 准备一个 getter setter 方法。以上是关于Android listview 计时器每秒运行一次的主要内容,如果未能解决你的问题,请参考以下文章