不幸的是,应用名称已停止

时间:2013-03-26 15:15:25

标签: java android

我是Java的新手,我正在尝试使用带有插件的eclipse为Android编写一个简单的应用程序。 这是代码:

package com.example.pushthebutton;

import java.util.Timer;
import java.util.TimerTask;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.widget.TextView;

public class MainActivity extends Activity {
    int counter = 30;
    TextView label;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        int delay = 0; 
        int period = 1000;
        Timer timer = new Timer();
        label = (TextView) findViewById(R.id.textView1);
        timer.scheduleAtFixedRate(new TimerTask() {
                public void run() {
                    label.setText(String.valueOf("Time left: "));
                    counter--;
                }
            }, delay, period);
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

}

我在模拟器中运行后,它说:“不幸的是,应用名称已停止。” logcat的:

03-26 15:05:47.499: E/AndroidRuntime(1269): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
03-26 15:05:47.499: E/AndroidRuntime(1269):     at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:4746)
03-26 15:05:47.499: E/AndroidRuntime(1269):     at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:823)
03-26 15:05:47.499: E/AndroidRuntime(1269):     at android.view.View.requestLayout(View.java:15473)
03-26 15:05:47.499: E/AndroidRuntime(1269):     at android.view.View.requestLayout(View.java:15473)
03-26 15:05:47.499: E/AndroidRuntime(1269):     at android.view.View.requestLayout(View.java:15473)
03-26 15:05:47.499: E/AndroidRuntime(1269):     at android.view.View.requestLayout(View.java:15473)
03-26 15:05:47.499: E/AndroidRuntime(1269):     at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:318)
03-26 15:05:47.499: E/AndroidRuntime(1269):     at android.view.View.requestLayout(View.java:15473)
03-26 15:05:47.499: E/AndroidRuntime(1269):     at android.widget.TextView.checkForRelayout(TextView.java:6452)
03-26 15:05:47.499: E/AndroidRuntime(1269):     at android.widget.TextView.setText(TextView.java:3696)
03-26 15:05:47.499: E/AndroidRuntime(1269):     at android.widget.TextView.setText(TextView.java:3554)
03-26 15:05:47.499: E/AndroidRuntime(1269):     at android.widget.TextView.setText(TextView.java:3529)
03-26 15:05:47.499: E/AndroidRuntime(1269):     at com.example.pushthebutton.MainActivity$1.run(MainActivity.java:24)
03-26 15:05:47.499: E/AndroidRuntime(1269):     at java.util.Timer$TimerImpl.run(Timer.java:284)
03-26 15:05:47.659: E/StrictMode(628): null

我是Java新手。我不知道它可能是什么。

3 个答案:

答案 0 :(得分:4)

您无法从与UI线程不同的线程更新每个视图:

以这种方式更改您的代码:

timer.scheduleAtFixedRate(new TimerTask() {
            public void run() {

                runOnUiThread(new Runnable()
                    public void run() {
                        label.setText(String.valueOf("Time left: "));
                        counter--;
                        }
                  ));

            }
        }, delay, period);
}

通过这种方式,您要求Android在setText

上执行UI Thread来电

答案 1 :(得分:2)

试试这个:

 timer.scheduleAtFixedRate(new TimerTask() {
            public void run() {
                runOnUiThread(new Runnable() {
                @Override
        public void run() {
        label.setText(String.valueOf("Time left: "));
                    counter--;
        }
            }
          }
        }, delay, period);

您正在从非ui线程修改UI线程,即计时器。

答案 2 :(得分:1)

  

异常只有创建视图层次结构的原始线程才能触及其视图。

你不能这样做。

label.setText(String.valueOf("Time left: "));

这样做。

runOnUiThread(new Runnable() {
   public void run() {
      //Update UI Here
   }
});

OR Handler执行此操作。

实施例

void startHeavyDutyStuff() {

  // Here is the heavy-duty thread
  Thread t = new Thread() {

      public void run() {
          while (true) {

              mResults = doSomethingExpensive();

              //Send update to the main thread
              messageHandler.sendMessage(Message.obtain(messageHandler, mResults)); 
          }

      }
  };
  t.start();
}

// Instantiating the Handler associated with the main thread.
private Handler messageHandler = new Handler() {

      @Override
      public void handleMessage(Message msg) {  
          switch(msg.what) {
              //handle update
              //.....
          }
      }

  };
}