我开发了一个应用程序,在Android模拟器屏幕上以指定的间隔显示一些文本。我正在使用Handler类。下面是我的代码片段:
handler = new Handler();
Runnable r = new Runnable() {
public void run() {
tv.append("Hello World");
}
};
handler.postDelayed(r, 1000);
当我运行这个应用程序时,文本只显示一次。为什么?
一个有趣的例子是,你可以连续看到一个计数器/秒表在不同的线程中运行。还显示gps定位。而主活动用户界面线程已经在那里。
摘录:
try {
cnt++; scnt++;
now=System.currentTimeMillis();
r=rand.nextInt(6); r++;
loc=lm.getLastKnownLocation(best);
if(loc!=null) {
lat=loc.getLatitude();
lng=loc.getLongitude();
}
Thread.sleep(100);
handler.sendMessage(handler.obtainMessage());
} catch (InterruptedException e) {
Toast.makeText(this, "Error="+e.toString(), Toast.LENGTH_LONG).show();
}
要查看代码,请参见这里:
线程示例显示GPS位置和当前时间运行与主活动的用户界面线程
对你的例子的简单修复是:
handler = new Handler();
final Runnable r = new Runnable() {
public void run() {
tv.append("Hello World");
handler.postDelayed(this, 1000);
}
};
handler.postDelayed(r, 1000);
或者我们可以使用普通线程为例(与原来的Runner):
Thread thread = new Thread() {
@Override
public void run() {
try {
while(true) {
sleep(1000);
handler.post(this);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
thread.start();
您可以将可运行对象视为可以发送到消息队列执行的命令,而将处理程序视为用于发送该命令的帮助对象。
更多详情请访问http://developer.android.com/reference/android/os/Handler.html
科特林
private lateinit var runnable: Runnable
override fun onCreate(savedInstanceState: Bundle?) {
val handler = Handler()
runnable = Runnable {
// do your work
handler.postDelayed(runnable, 2000)
}
handler.postDelayed(runnable, 2000)
}
Java
Runnable runnable;
Handler handler;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
handler = new Handler();
runnable = new Runnable() {
@Override
public void run() {
// do your work
handler.postDelayed(this, 1000);
}
};
handler.postDelayed(runnable, 1000);
}
我认为可以改进Alex2k8的第一个解决方案,以提高每秒更新的正确性
1.原始代码:
public void run() {
tv.append("Hello World");
handler.postDelayed(this, 1000);
}
2.分析
在以上成本中,承担tv。append("Hello Word")花费T毫秒,显示500次后延迟时间为500*T毫秒
长时间运行会增加延时
3.解决方案
只需改变postDelayed()的顺序,以避免延迟:
public void run() {
handler.postDelayed(this, 1000);
tv.append("Hello World");
}