1

所以我环顾四周,看到一些关于类似事情的帖子,但它们都与地理定位有关,我想做的只是一个简单的计时器。基本上,我使用 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)

我认为这是尝试设置视图文本的问题,但事实并非如此,因为在注释掉设置的文本部分后它仍然是错误的

4

3 回答 3

3

您正在尝试从非 UI 线程更新您的 UI,因此您需要将您的东西放入其中以更新 UIrunOnUiThread()

Activity_name.this.runOnUiThread(new Runnable() {
    public void run() {
      text.setText("Level " + Integer.toString(level)+ " will start in " +Integer.toString(time) + " seceonds." );
    }
});
于 2012-01-03T07:38:13.200 回答
0
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." );
        }
    };


}

您不能从线程修改 ui..您可以在处理程序的帮助下完成

于 2012-01-03T07:35:46.257 回答
0

当你的任务完成时放yourTaskObj.cancel().. 例如。task.cancel();

于 2013-06-17T12:47:45.310 回答