在那里放一个无限循环可以改变TextView吗?

时间:2019-04-04 01:21:36

标签: java android loops kotlin

我的第一个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方法,但我不知道是否存在这种情况。

2 个答案:

答案 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)
        }
    }
})