线程内的 while 循环不起作用?

发布于 2024-12-11 13:07:55 字数 1688 浏览 0 评论 0原文

我有一个非常简单的用户界面,我需要不断运行检查过程,所以我尝试使用带有 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();
}

I have a very simple UI and i need to constantly run a check process, so I am trying to use a Thread with a while loop.
When I run the loop with nothing but a Thread.sleep(1000) command, it works fine, but as soon as I put in a display.setText(), the program runs for a second on the emulator then quits. I cannot even see the error message since it exits so fast.

I then took the display.setText() command outside the thread and just put it directly inside onCreate, and it works fine (so there is no problem with the actual command).

here is my code, and help will be greatly appreciated.
Thank you!

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();
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

日裸衫吸 2024-12-18 13:07:55

您无法从非 UI 线程更新 UI。使用 Handler。像这样的东西可以工作:

// 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);
            // ...

或者,您可以使用 AsyncTask 而不是您自己的 Thread 类并重写 onProgressUpdate 方法。

You can't update the UI from a non-UI thread. Use a Handler. Something like this could work:

// 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);
            }

        }
    }
};

You could also avoid a Handler for this simple case and just use

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

Alternatively, you could use an AsyncTask instead of your own Thread class and override the onProgressUpdate method.

腹黑女流氓 2024-12-18 13:07:55

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

Not 100% certain, but I think it is a case of not being able to modify UI controls from a thread that did not create them?

总以为 2024-12-18 13:07:55

当您不在 UI 线程中时,不要使用 display3.setText("test") 使用:

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

When you are not in your UI thread, instead of display3.setText("test") use:

display3.post(new Runnable() {
    public void run() {
        display3.setText("test");
    {
});
一枫情书 2024-12-18 13:07:55

您应该将此代码封装在 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);
      }
   }  
}

然后只需从 onCreate 方法启动任务即可。

You should encapsulate this code in an AsyncTask instead. Like so:

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);
      }
   }  
}

Then just launch the task from your onCreate method.

枕花眠 2024-12-18 13:07:55

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

  1. 使用Handler
  2. 使用AsyncTask
  3. 使用LocalBroadcast
  4. 如果进程是观察者模式,可以使用RxJava

In non-UI thread,you can't update UI.In new Thread,you can use some methods to notice to update UI.

  1. use Handler
  2. use AsyncTask
  3. use LocalBroadcast
  4. if the process is the observer pattern,can use RxJava
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文