虽然Loop内部的循环不起作用?

时间:2011-10-23 03:31:33

标签: android multithreading while-loop

我有一个非常简单的UI,我需要不断运行检查过程,所以我试图使用带有while循环的Thread。 当我使用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();
}

5 个答案:

答案 0 :(得分:3)

您无法从非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);
            }

        }
    }
};

您也可以避免使用Handler来处理这个简单的情况,只需使用

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

或者,您可以使用AsyncTask代替您自己的Thread类,并覆盖onProgressUpdate方法。

答案 1 :(得分:0)

不是100%肯定,但我认为这是一个无法从没有创建它们的线程修改UI控件的情况?

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

您应该将此代码封装在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方法启动任务。

答案 4 :(得分:-1)

在非UI线程中,您无法更新UI。在新线程中,您可以使用某些方法来注意更新UI。

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