Android 当线程内的循环不工作时?

Android 当线程内的循环不工作时?,android,multithreading,while-loop,Android,Multithreading,While Loop,我有一个非常简单的UI,我需要不断地运行一个检查过程,所以我尝试使用一个带有while循环的线程。 当我只使用Thread.sleep(1000)命令运行循环时,它工作正常,但只要我输入display.setText(),程序就会在模拟器上运行一秒钟,然后退出。我甚至看不到错误消息,因为它退出得太快了 然后我将display.setText()命令放在线程外部,直接放在onCreate内部,它工作正常(因此实际的命令没有问题) 这是我的代码,非常感谢您的帮助。 谢谢大家! public void

我有一个非常简单的UI,我需要不断地运行一个检查过程,所以我尝试使用一个带有while循环的线程。 当我只使用Thread.sleep(1000)命令运行循环时,它工作正常,但只要我输入display.setText(),程序就会在模拟器上运行一秒钟,然后退出。我甚至看不到错误消息,因为它退出得太快了

然后我将display.setText()命令放在线程外部,直接放在onCreate内部,它工作正常(因此实际的命令没有问题)

这是我的代码,非常感谢您的帮助。 谢谢大家!

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);



    on=(Button) findViewById(R.id.bon);
    off=(Button) findViewById(R.id.boff);
    display=(TextView) findViewById(R.id.tvdisplay);
    display2=(TextView) findViewById(R.id.tvdisplay2);
    display3=(TextView) findViewById(R.id.tvdisplay3);
    stopper=(Button) findViewById(R.id.stops);


    stopper.setOnClickListener(new View.OnClickListener() {


        @Override

        public void onClick(View v) {
            // TODO Auto-generated method stub
            if(boo=true)
            {
                boo=false;
                display3.setText("System Off");
            }
            else{
                boo=true;
            }
            }
    });





    Thread x = new Thread() {
        public void run() {
            while (boo) {
                 display3.setText("System On");

                try {
                    // do something here
                    //display3.setText("System On");

                    Log.d(TAG, "local Thread sleeping");
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    Log.e(TAG, "local Thread error", e);
                }

            }
        }
    };


    display3.setText("System On");
    display3.setText("System On");


    x.start();
}

无法从非UI线程更新UI。使用一个。类似这样的方法可能会奏效:

// inside onCreate:
final Handler handler = new Handler();
final Runnable updater = new Runnable() {
    public void run() {
        display3.setText("System On");
    }
};

Thread x = new Thread() {
    public void run() {
        while (boo) {
            handler.invokeLater(updater);

            try {
                // do something here
                //display3.setText("System On");

                Log.d(TAG, "local Thread sleeping");
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                Log.e(TAG, "local Thread error", e);
            }

        }
    }
};
对于这种简单的情况,您也可以避免使用处理程序,只需使用

        while (boo) {
            runOnUiThread(updater);
            // ...

或者,您可以使用一个而不是您自己的线程类,并重写
onProgressUpdate
方法。

不是100%确定,但我认为这是一种无法从未创建UI控件的线程修改UI控件的情况?

当您不在UI线程中时,而不是
display3.setText(“测试”)
使用:

display3.post(new Runnable() {
    public void run() {
        display3.setText("test");
    {
});

您应该将此代码封装在AsyncTask中。像这样:

private class MyTask extends AsyncTask<Void, Void, Void> {
  private Activity activity;
  MyTask(Activity activity){
    this.activity = activity;
  }  

  protected Long doInBackground() {
    while (true){
      activity.runOnUiThread(new Runnable(){
        public void run(){
          display3.setText("System On");
        }
      });
      try{
        Thread.sleep(1000);
      }catch (InterruptedException e) {
        Log.e(TAG, "local Thread error", e);
      }
   }  
}
私有类MyTask扩展了AsyncTask{
私人活动;
我的任务(活动){
这个。活动=活动;
}  
受保护的长doInBackground(){
while(true){
activity.runOnUiThread(新的Runnable(){
公开募捐{
display3.setText(“系统开启”);
}
});
试一试{
睡眠(1000);
}捕捉(中断异常e){
Log.e(标记“本地线程错误”,e);
}
}  
}

然后从onCreate方法启动任务。

在非UI线程中,您不能更新UI。在新线程中,您可以使用一些方法来通知更新UI

  • 使用处理程序
  • 使用异步任务
  • 使用本地广播
  • 如果进程是observer模式,那么可以使用RxJava

  • 与线程相关的代码将非常有用。欢迎使用stackoverflow!如果您发现答案有帮助,您可以投票支持!如果您觉得有人已经充分回答了您的问题,请单击答案旁边的复选标记以接受它。@Alanmore,使用原始Post添加的代码如果它是一个实例,您不需要将display3声明为final变量。但他在一个方法中声明了“display3”。他在一个方法中初始化了它。我在他的代码中没有看到声明
    TextView display3
    。@user947659我添加了一个指向处理程序文档的链接以及一些示例代码。在尝试解决方案之前,我在线程中设置了display.setText命令,就像在代码中一样,但我只是在循环。你能告诉我为什么它不使用while循环就可以工作吗?它仍然在从非UI线程修改UI。你不应该从UI线程以外的任何东西修改UI;它有时可能会工作,但这取决于运气,永远不应该依赖。