使用Sharepreference+Thread+Handler进行异步处理实现倒计时功能

来源:互联网 发布:winphone软件下载 编辑:程序博客网 时间:2024/06/06 07:14

之前我写了一篇博文是重写了Button实现在控件内部进行的倒计时功能,但是存在一定的局限,详情可以看之前的博文:

《Android自定义TimeButton实现倒计时按钮》:http://blog.csdn.net/ssbby/article/details/69258672;

这篇博文主要使用Sharepreference+Thread+Handler进行异步处理实现倒计时功能,解决了长时间倒计时在APP退出或者其他状态下返回之后,无法继续倒计时或者倒计时开始点不准确的问题,具体思路如下:

(1)先确定倒计时时长,转化为自己所需的时间形式,即hh:mm(二十四小时制HH:mm)或者秒的形式显示倒计时,存为time,然后在本地创建一个Sharepreference文件来存储倒计时开始的时间点First_time(假设用户点击了倒计时控件,或者在调用了倒计时开始的回调方法(不由用户开始倒计时),也就是倒计时第一次开始的时间戳为First_time,假如用户退出当前界面,那么第二次进入界面的时间戳为second_time,倒计时重新开始的时间点就为我们之前预定的倒计时时间-(second_time-First_time);

(2)在第一步的Sharepreference轻量级存储的基础上,使用Thread+Handler进行异步处理实现倒计时功能,使用run()方法每秒发送一次带obj的请求,handler接收请求获取对应的obj,这里的obj就是倒计时的开始点,然后每执行一次,就执行time--的操作,然后handler接收后刷新对应控件上的显示文字即可;

(3)在开始的地方调用thread.start()即可。

这可以解决在app被用户主动kill的情况下重新打开也可以开始倒计时。

老规矩,上图:


主要的代码段如下:

1.在对应开始倒计时的地方使用Sharepreference存储:

public static SharedPreferences mSharedPreferences;...(这里是倒计时按钮的点击事件回调方法)//获取小时SimpleDateFormat hour = new SimpleDateFormat("HH");String date1 = hour.format(new java.util.Date());//获取分钟SimpleDateFormat min = new SimpleDateFormat("mm");String date2 = min.format(new java.util.Date());//获取秒SimpleDateFormat soc = new SimpleDateFormat("ss");String date3 = soc.format(new java.util.Date());//时间转换成秒的总和来计算first_time = String.valueOf(Integer.parseInt(date1)*60                        + Integer.parseInt(date2)*60                        + Integer.parseInt(date3));time1 = 299;(因为在run中执行了time1--,所以设置为299为了满足run开始的条件。。)//保存数据到本地SharePrefencesUtil.saveFirstTime(first_time,mContext);...
2.在第二次进入界面的时候更改time的值

public class CarDetialActivity extends Activity{...private int time1;//倒计时时间private int cha;//时间差private int first_time_i;private String time_text;private String first_time;//按下按钮的系统时间private int second_time;//第二次进入的系统时间...    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.cardetial_acticity);...//对是否有点击倒计时进行判断        mSharedPreferences = mContext.getSharedPreferences("First_Time", Context.MODE_PRIVATE);        Log.e("First_Time",mSharedPreferences.getString("first_time",""));        if (mSharedPreferences.getString("first_time","").equals("")){    //修改按钮的可点击和背景            car_wait_button.setEnabled(true);            car_wait_button.setBackground(getResources().getDrawable(R.drawable.login_button_bg));        }else {            //获取小时            SimpleDateFormat hour = new SimpleDateFormat("HH");            String date1 = hour.format(new java.util.Date());            //获取分钟            SimpleDateFormat min = new SimpleDateFormat("mm");            String date2 = min.format(new java.util.Date());            //获取秒            SimpleDateFormat soc = new SimpleDateFormat("ss");            String date3 = soc.format(new java.util.Date());            //时间转换成秒的总和来计算            second_time = Integer.parseInt(date1)*60                    + Integer.parseInt(date2)*60                    + Integer.parseInt(date3);            first_time_i = Integer.parseInt(mSharedPreferences.getString("first_time",""));            if(second_time - first_time_i >= 300){                time1 = 300;                car_wait_button.setEnabled(true);                car_wait_button.setBackground(getResources().getDrawable(R.drawable.login_button_bg));            }else {                cha = second_time - first_time_i;                time1 = 300 - cha;                car_wait_button.setEnabled(false);                car_wait_button.setBackground(getResources().getDrawable(R.drawable.false_btn));            }        }}
3.使用 Thread+Handler进行异步处理实现倒计时功能

先新建一个handler如下:

private Handler handler = new Handler() {        public void handleMessage(Message msg) {            switch(msg.what){//执行不同的操作,2为倒计时                case 1:                    sendWaitRequest(duration,carPlaceId);                    break;                case 2:            // 判断倒计时到和-1的时候结束                    if (msg.obj.equals(0) || msg.obj.equals(-1)){                        SharePrefencesUtil.delateFirstTime(mContext);                        car_wait_button.setEnabled(true);                        car_wait_button.setText("点我排队");                        car_wait_button.setBackground(getResources().getDrawable(R.drawable.login_button_bg));                    }else {                        time_text = String.valueOf(msg.obj);                        car_wait_button.setText(time_text + "秒后重新排队");                        car_wait_button.setBackground(getResources().getDrawable(R.drawable.false_btn));                    }                    break;            }        }    };
线程如下:

public class TimerThread implements Runnable {        @Override        public void run() {            // TODO Auto-generated method stub            while (true) {                try {                    Thread.sleep(1000);// 线程暂停1秒,单位毫秒                    Message message = new Message();                    message.what = 2;                    if (time1 >= 0 && time1 < 300){                        time1--;                        message.obj = time1;                        handler.sendMessage(message);// 发送消息                    }                } catch (InterruptedException e) {                    // TODO Auto-generated catch block                    e.printStackTrace();                }            }        }    }
我是在onCreate()中调用开始此线程

new Thread(new TimerThread()).start();//启动倒计时线程
最后,在使用由于这个thread.stop()和thread.destory()因为安全问题被禁用,所以这里可能会出现线程多开的问题,我们只需要设置一个flag判断是否需要开始线程,并且在线程方法内run()下的while(true)设置为while(flag)即可,关于解决线程多开的问题,之后再写一篇博文来记录这个问题~



0 0
原创粉丝点击