我有一个TextView。我想在按一下按钮1秒后更新其文本(附加“1”)。
public class HaikuDisplay extends Activity {
Method m;
Timer t;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
t = new Timer();
m = HaikuDisplay.class.getMethod("change");
}
//Event handler of the button
public void onRefresh(View view)
{
//To have the reference of this inside the TimerTask
final HaikuDisplay hd = this;
TimerTask task1 = new TimerTask(){
public void run(){
/*
* I tried to update the text here but since this is not the UI thread, it does not allow to do so.
*/
//Calls change() method
m.invoke(hd, (Object[])null);
}
};
t.schedule(task1, 1000);
}
public void change()
{
//Appends a "1" to the TextView
TextView t = (TextView)findViewById(R.id.textView1);
t.setText(t.getText() + "1");
}
//Event handler of another button which updates the text directly by appending "2".
//This works fine unless I click the first button.
public void onRefresh1(View view)
{
TextView t = (TextView)findViewById(R.id.textView1);
t.setText(t.getText() + "2");
}
}
考虑处理所有异常。
首次点击时,m.invoke
会InvocationTargetException
。但它在连续调用时调用方法change()
,没有任何异常(通过日志记录验证)。但它不会更新文本。我哪里错了?
另外,我在调试器中看到每次单击按钮时它都会创建一个新的Thread。那样就好。但是为什么不删除以前的Threads虽然它们的执行已经完成了?
答案 0 :(得分:3)
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
// Update UI
}
}, 1000);
点击按钮
实现此功能<强>更新强>
还有其他一些答案。 dtmilano建议另一个解决方案,除了他调用View类的postDelayed方法之外几乎与我的相同,在我的回答中我使用了postDelayed方法的处理程序类。
来自android的api引用,Handler的postDelayed方法说
runnable将在此处理程序所在的线程上运行 附接。
和View的postDelayed方法说
runnable将在用户界面线程上运行。
这是这两种解决方案之间的唯一区别。在我的答案中,而不是每次可以使用任何其他处理程序实例时创建新的Handler。然后runnable将在声明该特定处理程序的那个线程上运行。如果使用了postDelayed的EditText,则runnable方法将在用户界面线程上运行。
现在性能问题,都有相同的表现(如果有人可以证明我错了参考我会很高兴)
答案 1 :(得分:2)
做这样的事情
public void onRefresh1(View v) {
// You can have this in a field not to find it every time
final EditText t = (EditText) findViewById(R.id.textView1);
t.postDelayed(new Runnable() {
@Override
public void run() {
t.append("1");
}
}, 1000);
}
答案 2 :(得分:1)
这看起来很糟糕 - 您是否考虑过使用CountDownTimer?
new CountDownTimer(1000, 1000) {
public void onTick(long millisUntilFinished) {
// no-op
}
public void onFinish() {
change();
}
}.start();
这应该调用UI线程上的更改(从而更改文本),避免反射和线程错误。
答案 3 :(得分:0)
嗨使用以下代码。希望这会帮助你 。
new java.util.Timer().schedule(
new java.util.TimerTask() {
@Override
public void run() {
// your code here
}
},
1000
);
也看看这个问题。
display data after every 10 seconds in Android
你也可以试试这个。
private Handler handler = new Handler();
private Runnable runnable = new Runnable() {
public void run() {
doStuff();
/*
* Now register it for running next time
*/
handler.postDelayed(this, 1000);
}
};
**EDIT 3**
Try with this once you are need to enable once (i mean if you put your code in yourmethod()== this will get automatically call 1 seconds once.
private Timer timer;
TimerTask refresher;
// Initialization code in onCreate or similar:
timer = new Timer();
refresher = new TimerTask() {
public void run() {
yourmethod();
};
};
// first event immediately, following after 1 seconds each
timer.scheduleAtFixedRate(refresher, 0,100);