Java 为什么在更新TextView时获取资源$NotFoundException?

Java 为什么在更新TextView时获取资源$NotFoundException?,java,android,multithreading,Java,Android,Multithreading,我正在为android编写一个简单的秒表应用程序,当按下start时,它会保持计数器每秒更新一次,然后用相同的按钮暂停计数器。在main.xml布局中,我有一个文本视图和一个按钮,其他什么都没有。 这是我到目前为止写的 public class MainActivity extends Activity implements View.OnClickListener { private Button btnToggle; private TextView tvStopwatch

我正在为android编写一个简单的秒表应用程序,当按下start时,它会保持计数器每秒更新一次,然后用相同的按钮暂停计数器。在main.xml布局中,我有一个文本视图和一个按钮,其他什么都没有。 这是我到目前为止写的

public class MainActivity extends Activity implements View.OnClickListener {

    private Button btnToggle;
    private TextView tvStopwatch;
    public Handler updateStopwatch;

    private enum Status {
        WORKING,
        STOPPED
    }

    private Status stopwatchStatus;

    private void toggleStatus() {
        if (stopwatchStatus == Status.WORKING) {
            stopwatchStatus = Status.STOPPED;
            Stopwatch.getStopwatch().dispose();
            btnToggle.setText("Start");
        }else{
            stopwatchStatus = Status.WORKING;
            Stopwatch.getStopwatch().start();
            btnToggle.setText("Stop");
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        initView();
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btnToggle:
                toggleStatus();
                break;
        }
    }

    private void initView() {
        btnToggle = (Button) findViewById(R.id.btnToggle);
        tvStopwatch = (TextView) findViewById(R.id.tvStopwatch);

        updateStopwatch = new Handler(){
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                tvStopwatch.setText(msg.what);
            }
        };

        Stopwatch.getStopwatch().setHandler(updateStopwatch);
        btnToggle.setOnClickListener(this);

        stopwatchStatus = Status.STOPPED;
    }



    public static class Stopwatch {

        private int timestamp;

        private boolean working;

        private Handler updateStopwatch;

        private Stopwatch() {

        }

        private static Stopwatch stopwatch;

        public static Stopwatch getStopwatch() {

            if (stopwatch == null) {
                stopwatch = new Stopwatch();
            }
            return stopwatch;
        }

        public void setHandler(Handler updateStopwatch){
            this.updateStopwatch = updateStopwatch;
        }

        public void start() {

            if (!working) {

                working = true;

                Thread tick = new Thread() {
                    public void run() {
                        while (working) {
                            try {
                                sleep(1000);
                            } catch (InterruptedException ex) {
                                ex.printStackTrace();
                            } finally {
                                timestamp++;
                                updateStopwatch.sendEmptyMessage(timestamp);
                            }
                        }
                    }
                };

                tick.start();
            }
        }

        public void dispose() {
            working = false;
        }
    }
}
关键是,我希望我的秒表工作在它的独立线程中,并且在我的主UI线程中有一个处理程序,它将不断更新TextView,但是当我调试我的应用程序时,它会不断在这一行抛出异常

tvStopwatch.setText(msg.what)

我是新手,所以我想我只是缺少了一些基本的东西。 这也是异常的日志

android.content.res.Resources$NotFoundException: String resource ID #0x1
            at android.content.res.Resources.getText(Resources.java:1057)
            at android.widget.TextView.setText(TextView.java:4186)
            at unisoftdevelopment.com.stopwatch.MainActivity$1.handleMessage(MainActivity.java:61)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:5279)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:511)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1102)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:869)
            at dalvik.system.NativeStart.main(Native Method)

请帮助找出问题,谢谢提前解答。

常见错误:
setText()
的重载采用整数(必须是字符串资源ID,例如R.string.my_string)

当您收到信息时:

tvStopwatch.setText(msg.what);
它试图将
msg.what
解析为字符串资源,当找不到它时崩溃。您应该将时间戳转换为字符串,并使用该字符串:

tvStopwatch.setText(String.valueOf(msg.what));

常见错误:
setText()
的重载采用整数(必须是字符串资源ID,例如R.string.my_string)

当您收到信息时:

tvStopwatch.setText(msg.what);
它试图将
msg.what
解析为字符串资源,当找不到它时崩溃。您应该将时间戳转换为字符串,并使用该字符串:

tvStopwatch.setText(String.valueOf(msg.what));

omg)是的,这就是问题所在,非常感谢)我非常关心开始错过此类错误的处理程序和线程)如果您不介意的话,还有一个问题。它工作正常,但当我在第4秒钟按暂停按钮时,它仍然会将textview更新为5,我想是因为处理程序的消息已经在队列中,然后停止更新,我如何解决这个问题?在将
working
设置为false后,您只会在睡觉前检查它的值。您应该在睡眠前后检查它(例如,
如果(!working)updateStopwatch.sendEmptyMessage(timestamp);
)omg))是的,这就是问题所在,非常感谢)如果您不介意的话,我非常关心开始错过此类错误的处理程序和线程)还有一个问题。它工作正常,但当我在第4秒钟按暂停按钮时,它仍然会将textview更新为5,我想是因为处理程序的消息已经在队列中,然后停止更新,我如何解决这个问题?在将
working
设置为false后,您只会在睡觉前检查它的值。您应该在睡眠前后检查它(例如,
if(!working)updateStopwatch.sendEmptyMessage(timestamp);