我的第一个Android项目,我的第一个Kotlin项目(Java示例将帮助我做到这一点)
问题是这样的: 我有一个TextView。我可以用代码更改文本。但是问题在于,看来我的活动必须结束,才能对gui进行更改。
myTextView.setText("x = $x") //this works once
do{
myTextView.setText("x = $x") //this doesnt work
println("x = $x") //this works on standart io
x++
}while(true)
do{
myTextView.setText("x = $x") //this doesnt work until x reaches its limit
x++
}while(x<100)
到目前为止我尝试过的是:
使用HandlerThread启动另一个线程,然后在此处尝试(没有用,因为“只有创建视图层次结构的原始线程才能触摸其视图。”)首先我的代码在onCreate中,我意识到将其移动到onResume是一个更好的主意,这样,每次我切换到主屏幕并返回时,它至少会设置文本。但这仍然没有解决办法。
我唯一想到的解决方法是在同一线程上使用Handler.post()创建一个循环,但是我不确定这是否可行,这似乎是错误的方式,我希望使用while以相同的方式循环,也可以在standartio上与println()一起使用。也许我需要在循环内部调用某种刷新gui方法,但我不知道是否存在这种情况。
答案 0 :(得分:0)
目前尚不清楚您要在应用中执行的操作...如果一个简单的TextView
最多可以计数100,那么您将不得不使用单独的线程来进行计数和等待,如果您不希望您的应用程序运行缓慢。
在android系统中,Activity的UI线程本质上处于恒定循环中,等待用户输入和对视图的更改后将其发布到队列中,并按顺序处理。因此,建议将业务逻辑置于主线程之外。任何长时间运行的操作都会延迟它的工作-计算视图外观并每秒刷新屏幕60次。
一种实现方法是使用AsyncTask
,这是一种创建运行某些业务逻辑的新线程的方法,该方法提供了在完成主UI线程后对其进行更新的方法。
在您的MainActivity
中创建一个如下所示的内部类:
private class CounterTask extends AsyncTask<Integer, Integer, Boolean> {
@Override
protected Boolean doInBackground(Integer... integers) {
int count = 100;
for (int i = 0; i < count; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
publishProgress(i);
}
return true;
}
@Override
protected void onProgressUpdate(Integer... status) {
super.onProgressUpdate(status);
int current = status[0];
TextView textView = findViewById(R.id.counter_text_view);
textView.setText(String.valueOf(current));
}
}
然后在“活动”的onCreate
方法中,如下创建并执行此任务:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Run your counter task
CounterTask task = new CounterTask();
task.execute();
}
答案 1 :(得分:0)
问题:您要在不定式循环或上限循环中更新TextView。
解决方案::一起使用Handler.post()
和Handler.postDelayed()
。
情况1:无限循环更新TextView。
val uiHandler = Handler()
var x = 1
uiHandler.post(object : Runnable {
override fun run() {
myTextView.setText("x = $x")
println("x = $x")
x++
// Delay 100 milliseconds to see the text is updated in the TextView.
// You can set this to smaller value, such as 10 or 50, etc...
uiHandler.postDelayed(this, 100)
}
})
情况2:循环更新具有上限的TextView。
val uiHandler = Handler()
var x = 1
uiHandler.post(object : Runnable {
override fun run() {
myTextView.setText("x = $x")
println("x = $x")
x++
// Exit the loop when it reaches the upper bound (100 in this case).
if (x < 100) {
uiHandler.postDelayed(this, 100)
}
}
})