Android TimerTask вылетает из программы Fatal Exception time-0

Итак, я осмотрелся и увидел несколько сообщений о похожих вещах, но все они были связаны с геолокацией, и все, что я пытаюсь сделать, это простой таймер. В основном я использую TimerTask для обратного отсчета с 30 секунд в классе активности. приложение аварийно завершает работу каждый раз, когда вызывается TimerTask. для целей контекста это дочернее действие от родителя, который вызвал его с помощью вызова startActivityForResult.

public class NewLevelActivity extends Activity {

    int time = 30;
    int level = 1;
    TextView text;
    TimerTask task;


   @Override
   public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.new_level);
      text = (TextView) findViewById(R.id.newLevelText);
      level = WholettheballoutActivity.level;


      task = new TimerTask() {
        public void run() {
                    time--;
                    //text.setText("Level " + Integer.toString(level)+ " will start in " +Integer.toString(time) + " seceonds." );
                    new Timer().schedule(task,1000);
               }
        };

        new Timer().schedule(task,1000);

   }


   @Override
   protected void onPause() {
       super.onPause();

   }

   @Override
   protected void onResume() {
       super.onResume();
    }




}

Logcat показывает это

01-03 01:08:57.630: ERROR/AndroidRuntime(19618): FATAL EXCEPTION: Timer-0
01-03 01:08:57.630: ERROR/AndroidRuntime(19618): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
01-03 01:08:57.630: ERROR/AndroidRuntime(19618):     at android.view.ViewRoot.checkThread(ViewRoot.java:3441)
01-03 01:08:57.630: ERROR/AndroidRuntime(19618):     at android.view.ViewRoot.requestLayout(ViewRoot.java:586)
01-03 01:08:57.630: ERROR/AndroidRuntime(19618):     at android.view.View.requestLayout(View.java:10781)
01-03 01:08:57.630: ERROR/AndroidRuntime(19618):     at android.view.View.requestLayout(View.java:10781)
01-03 01:08:57.630: ERROR/AndroidRuntime(19618):     at android.view.View.requestLayout(View.java:10781)
01-03 01:08:57.630: ERROR/AndroidRuntime(19618):     at android.view.View.requestLayout(View.java:10781)
01-03 01:08:57.630: ERROR/AndroidRuntime(19618):     at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:257)
01-03 01:08:57.630: ERROR/AndroidRuntime(19618):     at android.view.View.requestLayout(View.java:10781)
01-03 01:08:57.630: ERROR/AndroidRuntime(19618):     at android.widget.TextView.checkForRelayout(TextView.java:6052)
01-03 01:08:57.630: ERROR/AndroidRuntime(19618):     at android.widget.TextView.setText(TextView.java:2826)
01-03 01:08:57.630: ERROR/AndroidRuntime(19618):     at android.widget.TextView.setText(TextView.java:2691)
01-03 01:08:57.630: ERROR/AndroidRuntime(19618):     at android.widget.TextView.setText(TextView.java:2666)
01-03 01:08:57.630: ERROR/AndroidRuntime(19618):     at org.kizik.WLTBO.NewLevelActivity$1.run(NewLevelActivity.java:43)
01-03 01:08:57.630: ERROR/AndroidRuntime(19618):     at java.util.Timer$TimerImpl.run(Timer.java:284)

что я считал проблемой при попытке установить текст представления, но это не так, потому что после комментирования текстовой части набора это все еще неправильно


person Kizik Studios    schedule 03.01.2012    source источник
comment
Я бы попытался сделать чистую сборку и убедиться, что она загружается нормально. Я не могу сосчитать, сколько раз я думал, что Eclipse загрузил apk на мое устройство, и я запускал старый код...   -  person nmjohn    schedule 03.01.2012


Ответы (3)


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

Activity_name.this.runOnUiThread(new Runnable() {
    public void run() {
      text.setText("Level " + Integer.toString(level)+ " will start in " +Integer.toString(time) + " seceonds." );
    }
});
person Lalit Poptani    schedule 03.01.2012
comment
теперь, куда мне поместить этот код и как мне его использовать, чтобы сделать счетчик. Кажется, что программа падает и перезапускается каждый раз, когда я вызываю TimerTask. - person Kizik Studios; 05.01.2012
comment
хорошо, это исправило проблему с пользовательским интерфейсом. Чтобы все это работало, я закоментировал новый таймер внутри TimerTask и сделал его sheduleAtFixedRate, и это сработало. - person Kizik Studios; 05.01.2012
comment
Вот почему я ненавижу Timers использовать Handlers это гораздо более полезная часть Android. - person Chris.Jenkins; 29.01.2013

public class NewLevelActivity extends Activity {

int time = 30;
int level = 1;
TextView text;
TimerTask task;




@Override
   public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.new_level);
      text = (TextView) findViewById(R.id.newLevelText);
      level = WholettheballoutActivity.level;


      task = new TimerTask() {
        public void run() {
                    time--;
                    textChangeHandler.sendEmptyMessage(0);
                    new Timer().schedule(task,1000);
               }
        };

        new Timer().schedule(task,1000);

   }


   @Override
   protected void onPause() {
       super.onPause();

   }

   @Override
   protected void onResume() {
       super.onResume();
    }

    private Handler textChangeHandler=new Handler(){
        @Override
        public void handleMessage(Message msg) {
                  text.setText("Level " + Integer.toString(level)+ " will start in " +Integer.toString(time) + " seceonds." );
        }
    };


}

Вы не можете изменить пользовательский интерфейс из потока. Вы можете сделать это с помощью обработчика

person Sai Mukesh    schedule 03.01.2012

поставьте yourTaskObj.cancel(), когда ваша задача будет завершена.. например. task.cancel();

person Pratik Butani    schedule 17.06.2013