2
public class MainActivity extends Activity {

    private Button Start, Reset, Stop;
    private EditText stop_watch, lblDate, lblTime;

    public MainActivity() {
        init();
    }

    private final UpdateClockThread ucThread = new UpdateClockThread();
    private final StopwatchThread swThread = new StopwatchThread();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Start = (Button)findViewById(R.id.button1);
        Stop = (Button)findViewById(R.id.button3);
        Reset = (Button)findViewById(R.id.button2);
        stop_watch = (EditText)findViewById(R.id.editText3);
        lblTime = (EditText)findViewById(R.id.editText2);
        lblDate = (EditText)findViewById(R.id.editText1);

        Start.setOnClickListener(new View.OnClickListener()
        {
            public void onClick(View v)
            {
                startactionPerformed();
            }
        });

        Stop.setOnClickListener(new View.OnClickListener()
        {
            public void onClick(View v)
            {
                stopactionPerformed();
            }
        });

        Reset.setOnClickListener(new View.OnClickListener()
        {
            public void onClick(View v)
            {
                resetactionPerformed();
            }
        });

    }

    public void init() {
    swThread.setDaemon(true);
    ucThread.setDaemon(true);
    swThread.start();
    ucThread.start();
    }

    /** Listens to the Start/Stop/Resume button. */

    void startactionPerformed() {
        swThread.go();
        //init();
    }

    void stopactionPerformed() {
        swThread.noGo();
    }

    void resetactionPerformed() {
        swThread.reset();
    }

    /** A thread that updates the current date & time. */
    private class UpdateClockThread extends Thread {
    /** The actual work of the thread. */
        public void run() {
            while (true) {
                lblTime.setText("ampm");
                Calendar now = Calendar.getInstance();
                String month = Integer.toString(now.get(Calendar.MONTH)+1);
                String date = Integer.toString(now.get(Calendar.DAY_OF_MONTH));
                String year = Integer.toString(now.get(Calendar.YEAR));
                String hour = Integer.toString(now.get(Calendar.HOUR));
                if (hour.equals("0")) hour = "12";
                String minute = Integer.toString(now.get(Calendar.MINUTE));
                if (minute.length() == 1) minute = "0" + minute;
                String second = Integer.toString(now.get(Calendar.SECOND));
                if (second.length() == 1) second = "0" + second;
                String ampm = now.get(Calendar.AM_PM) == Calendar.AM ? "AM" : "PM";
                lblDate.setText(month + "/" + date + "/" + year);
                lblTime.setText(hour + ":" + minute + ":" + second + " " + ampm);
                try {
                    sleep(500);
                } catch (InterruptedException e) {} 
            }
        }
    }

    /** A thread that keeps track of the stop watch & updates
     * the display accordingly.
    */
    class StopwatchThread extends Thread {
        /** Whether or not stop watch is running. */
        private boolean going = false;
        /** Stores elapsed milliseconds of previous runs. */
        private long prevElapsed = 0;
        /** Stores beginning time of this run. */
        private Date startDate = new Date();

        /** Returns elapsed time in milliseconds.
         *@return The elapsed time
         */
        private long elapsedTime() {
            return prevElapsed + (going ? new Date().getTime() - startDate.getTime() : 0);
        }
        /** Changes the number of elapsed milliseconds into a string.
         *@param time Number of elapsed milliseconds
         *@return The elapsed time as a string.
         */
        private String msToString(long time) {
            String ms, sec, min;
            if (time % 10 >= 5) //round to nearest hundredth
                time += 5;
            ms = Long.toString(time % 1000);
            while (ms.length() < 3)
            ms = "0" + ms;
            ms = ms.substring(0, ms.length() - 1);
            time /= 1000;
            sec = Long.toString(time % 60);
            if (sec.length() == 1) sec = "0" + sec;
            time /= 60;
            min = Long.toString(time);
            return min + ":" + sec + "." + ms;
        }

        /** Called when the stop watch is to go.
         */
        public void go() {
            startDate = new Date();
            going = true;
        }
        /** Called when the stop watch is to stop.
         */
        public void noGo() {
            prevElapsed = elapsedTime();
            going = false;
        }
        /** Resets the stop watch.
         */
        public void reset() {
            going = false;
            prevElapsed = 0;
        }
        /** Adds a lap to the list.
         */

        /** Main code of the thread.
         */
        public void run() {
            while (true) {
                stop_watch.setText(msToString(elapsedTime()));
                yield();
            }
        }
    }
}

我的应用程序正在强制关闭什么?线程有一些错误。但我无法弄清楚?

4

3 回答 3

1

runOnUiThread尝试从Activity http://developer.android.com/reference/android/app/Activity.html#runOnUiThread%28java.lang.Runnable%29方法中的线程与 UI 进行所有交互

编辑

private class UpdateClockThread extends Thread {
   public void run() {
       /* Do somthing expensive */
       ......

       /* Update UI */
       MainActivity.this.runOnUiThread(new Runnable() {
           @Override
           public void run() {
               /* Do UI update */;
               lblTime.setText("ampm");
               ......
           }
       });
   }
}
于 2012-10-31T16:11:55.877 回答
0

您应该在您的开发人员机器上运行 adb logcat。通常,如果您强制关闭,则会在日志中显示回溯。

于 2012-10-31T17:02:56.227 回答
0

您的课程StopwatchThread包含以下行:

stop_watch.setText(msToString(elapsedTime()));

这将不起作用,UI 也不会在UpdateClockThread. 这是因为您无法从后台线程修改 UI。您的后台线程应该:

  • 向在 UI 线程上创建的 a 发送消息Handler,以便Handler随后对 UI 进行更新,或者
  • 您可以将一个可运行的对象传递给runOnUiThread执行 UI 更新的对象。
于 2012-10-31T18:04:13.913 回答