繁体   English   中英

TextView.setText(…)在按钮的侦听器内无法循环运行

[英]TextView.setText(…) does not work in a loop inside the button's listener

假设我有一个按钮和一个标签。 我想在按钮侦听器中的循环中将标签更新100000次。 问题在于,我们看不到更新文本的过程,而只能看到最后一个设置值。

@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    generateLabel = findViewById(R.id.label);
    generateButton = findViewById(R.id.button);

    generateButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            for (int i = 0; i < 100000; i++) {
                generateLabel.setText("" + i);
            }
        }
    });
}

似乎我们必须先退出onClick(...)方法,然后才能将所有更改更新到标签。 因此,我尝试:

  • 运行我自己的线程,
  • 调用runOnUiThread(...),
  • 执行AsyncTask子类,

但是每次遇到异常情况时,我都不应修改来自原始线程的视图层次结构的视图。 甚至刷新标签并使标签volatile也无济于事。 有任何想法吗?

public static int counter = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    findViewById(R.id.button).setOnClickListener(
            new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    counter = 0;
                    new Runner().run();
                }
            }
    );
}

public class Runner implements Runnable {
    @Override
    public void run() {
        if(counter++ < 1000) {
            ((TextView) findViewById(R.id.label)).setText("Counter: " + counter);
            new Handler().postDelayed(new Runner(), 100);
        }
    }
}

这样做有多种原因,第一个原因是您试图在<〜1秒内将UI更新100,000次。请注意,当您调用setText()您实际上是在告诉系统渲染已传递的文本。 在<〜1秒内渲染和重新渲染10万次会导致您的应用崩溃。 现在,如果您要说的是,我将在某些后台线程中运行此线程,这也是不可能的,因为您只能在UI线程上执行UI工作,或者不能将主线程和BG线程用于此目的。 唯一的方法是在AsyncTask中使用onProgressUpdate() ,但通常用于此目的以外的用途,并且该方法的UI更新也发生在主线程上,因此它实际上在做现在和将来要做的相同的事情当然会导致崩溃。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM