Java TextView.setText(…)在按钮';听众

Java TextView.setText(…)在按钮';听众,java,android,multithreading,Java,Android,Multithreading,假设我有一个按钮和一个标签。我想在按钮侦听器中的循环中更新标签100000次。问题是,我们看不到更新文本的过程,而只看到最后一个设置值 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); generateLabel = findViewById(

假设我有一个按钮和一个标签。我想在按钮侦听器中的循环中更新标签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);
            }
        }
    });
}
@覆盖
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
generateLabel=findViewById(R.id.label);
generateButton=findViewById(R.id.button);
generateButton.setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图v){
对于(int i=0;i<100000;i++){
generateLabel.setText(“+i”);
}
}
});
}
看起来我们必须在对标签进行任何更改之前退出onClick(…)方法。所以,我试着:

  • 运行我自己的线程
  • 调用runOnUiThread(…)
  • 正在执行AsyncTask子类
但是每次我都会遇到一个异常,说我不应该修改来自原始线程的视图层次结构的视图。即使刷新标签并使其变得易变也无济于事。有什么想法吗?

公共静态整数计数器=0;
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);
        }
    }
}
@凌驾 创建时受保护的void(Bundle savedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewById(R.id.button).setOnClickListener( 新建视图。OnClickListener(){ @凌驾 公共void onClick(视图){ 计数器=0; 新跑步者().run(); } } ); } 公共类运行器实现可运行{ @凌驾 公开募捐{ 如果(计数器+++<1000){ ((TextView)findviewbyd(R.id.label)).setText(“计数器:”+计数器); new Handler().postDelayed(new Runner(),100); } } }
这不起作用的原因有很多,第一个原因是您试图在中更新UI 100000次,您可以使用AsyncTask,但无法在doInBackground中更新标签。所以重写onProgressUpdate。我不认为Wojciech Kazior在任何地方提到过,尽管他没有提到,for循环将在不到一秒的时间内执行10万次,大致上,除非他添加一个线程。在循环内睡眠,渲染调用将在不到一秒的时间内执行10万次。@Shiredede95 1。但是“setText”是一个同步函数,对吗?所以对我来说,文本从“0”变为“99999”应该是可见的,即使不到1秒。2.该应用程序没有因100000次呼叫而崩溃。3.暂停线程对我来说没有问题,如果有帮助的话,我可以这样做。我不好,我说应用程序会崩溃,对于较大的I值,如果你不添加某种延迟,应用程序将进入无响应状态。如果您按照@Dennick的建议以可运行的方式运行它,那么代码的执行将不会出现任何问题,尽管速度没有您希望的那么快。