• 【Android实验】线程的使用-计时器


    实验目的

    熟悉和掌握Android线程的使用

    实验要求

    1. 完成一个秒表,具备启停功能,正确使用工作线程完成界面刷新
    2. 分析秒表的计时是否准确,原因是什么,如何保证秒表计时准确?

    实验过程

    实验结果

    实验代码

    界面部分

    main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical" android:layout_width="match_parent"
        android:layout_height="match_parent">
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="秒表"
            android:textAlignment="center"
            android:textSize="40dp"
            />
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="00:00:00"
                android:id="@+id/tv_time"
                android:textAlignment="center"
                android:textSize="60dp"/>
            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:orientation="horizontal">
                    <Space
                        android:layout_width="120dp"
                        android:layout_height="match_parent"
                        android:layout_weight="1"
                        />
    
                <Button
                    android:id="@+id/btn_clear"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:text="清零"
                    android:textColor="#000000"
                    android:textSize="25dp"
                    android:background="#99FFFF"/>
    
                <Button
                    android:id="@+id/btn_start"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
                     android:text="计时"
                     android:layout_weight="1"
                     android:textSize="25dp"
                    android:background="#FFC8B4"
                    />
                <Button
                     android:id="@+id/btn_stop"
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
                     android:text="停止"
                     android:layout_weight="1"
                     android:textSize="25dp"
                    android:background="#CCFF99"
                    />
            </LinearLayout>
    </LinearLayout>
    

    核心代码

    Timer.java

    package com.example.administrator.exp5;
    
    import android.app.Activity;
    import android.content.Intent;
    import android.os.Handler;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Button;
    import android.widget.TextView;
    
    public class Timer extends AppCompatActivity {
        private static Handler handler = new Handler();
        private static TextView tv_time = null;
        private static Button btn_clear,btn_start,btn_stop;
    
        private static String time;
    
        private int min=0,sec=0,psec= 0;
    
        boolean runflag = true;
        int status = 0; // 0 - clear ; 1 - start ; 2 - stop
        long last,templast = -1;
    
        String str="";
    
        private Thread workThread;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
    
            tv_time = (TextView)findViewById(R.id.tv_time);
            btn_clear = (Button)findViewById(R.id.btn_clear);
            btn_start = (Button)findViewById(R.id.btn_start);
            btn_stop = (Button)findViewById(R.id.btn_stop);
    
            workThread = new Thread(null,RefreshLabel,"workThread");
            workThread.start();
            last = System.currentTimeMillis();
    
            btn_start.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    //计时开始
                    status = 1;
                    if(templast != -1)
                    {
                        last = templast;
                    }
                }
            });
            btn_stop.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    //停止计时
                    status = 2;
                    templast = last;
                }
            });
            btn_clear.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    min = sec = psec = 0;
                    //清零
                    status = 0;
                    last = System.currentTimeMillis();
                    tv_time.setText("00:00:00");
                    templast = -1;
                }
            });
        }
    
        private Runnable RefreshLabel = new Runnable() {
            @Override
            public void run() {
                try{
                    while(runflag)
                    {
                        Thread.sleep(50);
                        if(status == 1)
                        {
                            int t=0;
                            long tmp = System.currentTimeMillis();
                            long cha = tmp - last;
    
                            t = (int)cha/1000;
                            psec = (int)cha - t * 1000;
                            psec %= 100;
                            sec = t - ((int)t/60)*60;
                            min = (int)t/60;
                            if(min == 60)
                            {
                                min = 0;
                            }
                            str = "";
                            str = str + String.format("%02d",min) + ":" +String.format("%02d",sec) + ":" + String.format("%02d",psec);
    
                            tv_time.post(new Runnable() {
                                @Override
                                public void run() {
                                    tv_time.setText(str);
                                }
                            });
                        }
                    }
                }
                catch(InterruptedException e)
                {
                    e.printStackTrace();
                }
            }
        };
    }
    

    设计思路

        秒表需要完成停启功能,也就是说需要能够停下来,而且在停下来以后需要能够继续计时。这个计时的工作需要交付给一个子进程来做,每隔一段时间就刷新一次界面,从而达到计时的效果。
        如何使秒表计时更加准确?可以通过sleep(1000)来计时,或者采取不断访问系统时间的方式来计时。两种方式相比较,第二种方式更加准确,第一种解决方案由于sleep时间是人为设定的,跟手机的性能有一定关系,除此之外,由于程序间断性执行,这些时间也会计算到总时间中,所以第一种方案计时不准确。应该采用第二种计时方式。

    实验总结

        本实验主要是练习线程的使用,线程需要实现(Runnable)借口,并重载(run())函数,在该函数中写入秒表运行的代码,进行计算:

    private Runnable RefreshLabel = new Runnable(){
        @Override
        public void run(){
            try{
                
            }
            catch(InterruptedException e){
                e.printStackTrace();
            }
        }
    }
    

    然后创建Thread对象,将Runnable对象作为参数传递给Thread对象。

    private Thread workThread;
    workThread = new Thread(null,RefreshLabel,"workThread")
    

    需要的三个参数,第一个参数表示线程组,第二个参数是需要执行的Runnable对象,第三个参数是参数名称。

    关于时间计算:

    通过System.currentTimeMillis()函数返回当前计算机的时间所对应的毫秒数。

    时间换算如下:

    1min = 60s

    1s = 1000ms

    时间计算部分代码:

    long tmp = System.currentTimeMillis();
    long cha = tmp - last;
    t = (int)cha/1000;
    psec = (int)cha - t * 1000;
    psec %= 100;
    sec = t - ((int)t/60)*60;
    min = (int)t/60;
    if(min == 60)
    {
    	min = 0;
    }
    str = "";
    str = str + String.format("%02d",min) + ":" +String.format("%02d",sec) + ":" + String.format("%02d",psec);
    

    另外,由于单线程中,不能再UI线程外访问Android UI 工具包,则调用(View.post())方法,进行异步通信。实现界面的动态更新。

  • 相关阅读:
    Qt 查询字符串数据
    #include <stdint.h>
    滤波器设计-巴特沃尔斯低通滤波设计 转
    小波学习之二(单层一维离散小波变换DWT的Mallat算法C++实现优化)--转载
    机器学习之Bagging与随机森林笔记
    机器学习之决策树笔记
    机器学习之softmax回归笔记
    机器学习之逻辑回归(Logistic)笔记
    机器学习之模型拟合效果的判断笔记
    机器学习最小二乘法笔记
  • 原文地址:https://www.cnblogs.com/pprp/p/9874630.html
Copyright © 2020-2023  润新知