Пока Loop внутри Thread не работает? - PullRequest
0 голосов
/ 23 октября 2011

У меня очень простой пользовательский интерфейс, и мне нужно постоянно запускать процесс проверки, поэтому я пытаюсь использовать поток с циклом 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();
}

Ответы [ 5 ]

3 голосов
/ 23 октября 2011

Вы не можете обновить пользовательский интерфейс из не-пользовательского потока. Используйте обработчик . Примерно так может работать:

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

0 голосов
/ 03 февраля 2017

В потоке, не связанном с пользовательским интерфейсом, вы не можете обновить пользовательский интерфейс. В новом потоке вы можете использовать некоторые методы для уведомления об обновлении пользовательского интерфейса.

  1. использовать обработчик
  2. используйте AsyncTask
  3. использовать LocalBroadcast
  4. , если процесс является шаблоном наблюдателя, может использовать RxJava
0 голосов
/ 23 октября 2011

Вместо этого вы должны инкапсулировать этот код в 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.

0 голосов
/ 23 октября 2011

Если вы не в потоке пользовательского интерфейса, вместо display3.setText("test") используйте:

display3.post(new Runnable() {
    public void run() {
        display3.setText("test");
    {
});
0 голосов
/ 23 октября 2011

Не уверен на 100%, но я думаю, что это случай невозможности изменить элементы управления пользовательского интерфейса из потока, который их не создавал?

...