文档章节

自定义android计时器

龙扬凡
 龙扬凡
发布于 2014/05/01 21:03
字数 1206
阅读 1616
收藏 0

自定义计时器的原理很简单,主要用到广播机制BroadcastReceiver来实现Activity和Service之间的通讯。

Service在后台开辟一个线程,使用Thread.sleep(1000)来实现每隔1秒钟给handler发送一次信息,告诉handler进行时间的递增,再利用广播,把hour、minute、second(小时、分钟、秒)三个数据发送给Activity,在TextView上显现出来。

效果图如下~

废话不多说,下面上源码~

先是Activity的

package com.hzy.mychronometer;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import com.example.chronometer.R;
import com.hzy.mychronometer.TimeService.MyBinder;
public class Mychronometer extends Activity
{
 protected static final String ACTIONServiceTOActivity = "Service-Activity";//TimeService把时间变化告诉Mychronometer的广播
 protected static final String ACTIONActivityToService = "Activity-Service";//Mychronometer告知TimeService停止、开始、清零的广播
 
 //定义控件
 private TextView hourTxt;
 private TextView minTxt;
 private TextView secTxt;
 private Button start;
 private Button stop;
 private Button setZero;
 //时间数据
 private int hour;
 private int min;
 private int sec;
 //广播
 private IntentFilter filter;
 private FromServiceReceiver receiver;//接收TimeService传来的时间变化数据
 
 private boolean ifBind;    //判断是否绑定了服务
 
 @Override
 protected void onCreate(Bundle savedInstanceState)
 {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.my_layout);
  
  ifBind=false;        //一开始没有绑定服务
  
  receiver=new FromServiceReceiver();   //初始化广播
  filter=new IntentFilter();
  filter.addAction(ACTIONServiceTOActivity);
  
  findview();         //初始化控件
  setListener();        //给控件设置监听
  hourTxt.setText("00");
  minTxt.setText("00");
  secTxt.setText("00");
 }
 
 
 @Override
 protected void onResume()
 {
  super.onResume();
  registerReceiver(receiver, filter);   //注册广播
 }

 @Override
 protected void onPause()
 {
  super.onPause();
  unregisterReceiver(receiver);    //注销广播
 }

 @Override
 protected void onDestroy()
 {
  super.onDestroy();
  unBind();
 }

 private void setListener()
 {
  start.setOnClickListener(new Button.OnClickListener()
  {
   @Override
   public void onClick(View v)
   {
    bindService();      //启动TimeService服务,开始计时
   }
  });
  stop.setOnClickListener(new Button.OnClickListener()
  {
   
   @Override
   public void onClick(View v)
   {
    stopService();      //暂停服务,暂停计时
   }
  });
  setZero.setOnClickListener(new Button.OnClickListener()//清零
  {
   
   @Override
   public void onClick(View v)
   {
    unBind();       //解除绑定,销毁Service
    hourTxt.setText("00");
    minTxt.setText("00");
    secTxt.setText("00");
   }
  });
 }
 
 protected void stopService()     //告诉TimeService.java停止线程
 {
  Intent intentStart=new Intent();
  intentStart.putExtra("StartOrNot",false);
  intentStart.setAction(ACTIONActivityToService);
  sendBroadcast(intentStart);
 }
 protected void unBind()       //解除绑定
 {
  if (ifBind)
  {
   Intent intentStart=new Intent();
   intentStart.putExtra("StartOrNot",false);
   intentStart.setAction(ACTIONActivityToService);
   sendBroadcast(intentStart);
   unbindService(conn);
   Toast.makeText(this, "unbind", Toast.LENGTH_LONG).show();
   ifBind=false;
  }
 }
 protected void bindService()     //启动TimeService服务,开始计时
 {
  if(!ifBind)//没有绑定则绑定
  {
   Intent intent=new Intent(Mychronometer.this, TimeService.class);
   bindService(intent, conn, Context.BIND_AUTO_CREATE);//绑定服务
   ifBind=true;
  }
  else//已经绑定则广播告诉TimeService.java开启线程
  {
   Intent intentStart=new Intent();
   intentStart.putExtra("StartOrNot",true);
   intentStart.setAction(ACTIONActivityToService);
   sendBroadcast(intentStart);
  }
 }
 
 private ServiceConnection conn=new ServiceConnection()
 {
  @Override
  public void onServiceDisconnected(ComponentName name)
  {
   
  }
  
  @Override
  public void onServiceConnected(ComponentName name, IBinder binder)
  {
  }
 };
 private void findview()
 {
  hourTxt=(TextView)findViewById(R.id.hour);
  minTxt=(TextView)findViewById(R.id.min);
  secTxt=(TextView)findViewById(R.id.sec);
  start=(Button)findViewById(R.id.ButtonStart);
  stop=(Button)findViewById(R.id.ButtonStop);
  setZero=(Button)findViewById(R.id.ButtonSet0);
 }
 class FromServiceReceiver extends BroadcastReceiver //接收TimeService.java返回的时间信息
 {
  @Override
  public void onReceive(Context context, Intent intent)
  {
   Bundle bundle1=intent.getExtras();
   hour=bundle1.getInt("hour",0);
   min=bundle1.getInt("min",0);
   sec=bundle1.getInt("sec",0);
   
   
   //把时间数据setText
   if(hour<10)
    hourTxt.setText("0"+hour);
   else
    hourTxt.setText(hour+"");
   
   if(min<10)
    minTxt.setText("0"+min);
   else
    minTxt.setText(min+"");
   
   if(sec<10)
    secTxt.setText("0"+sec);
   else
    secTxt.setText(sec+"");
  }
 }
}


 

最后是Service~

 package com.hzy.mychronometer;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
public class TimeService extends Service implements Runnable
{
 protected static final String ACTIONServiceTOActivity = "Service-Activity";//TimeService把时间变化告诉Mychronometer的广播
 protected static final String ACTIONActivityToService = "Activity-Service";//Mychronometer告知TimeService停止、开始、清零的广播
 private ServiceReceiver serviceReceiver;
 private IntentFilter filter;
 private MyBinder binder =new MyBinder();
 private Handler handler;
 private Thread timecountThread;    //告诉handler时间递增的线程
 private boolean flagIfContinnute;   //接收timecountThread线程的标志
 private boolean timeAdd;     //handler执行时间递增的信息标志
 
 //时间数据
 private int hour;
 private int min;
 private int sec;
 
 private Intent intentSendTime;    //传递时间数据的Intent
 @Override
 public IBinder onBind(Intent intent)
 {
  return binder;
 }
 @Override
 public boolean onUnbind(Intent intent)
 {
  return super.onUnbind(intent);
 }
 public class MyBinder extends Binder
 {
  public TimeService getService()
  {
   return TimeService.this;
  }
 }
 @Override
 public void onCreate()
 {
  super.onCreate();
  
  serviceReceiver=new ServiceReceiver();   //初始化广播
  filter=new IntentFilter();
  filter.addAction(ACTIONActivityToService);
  registerReceiver(serviceReceiver, filter);   //注册广播
  
  //初始化变量
  flagIfContinnute=false;
  hour=0;
  min=0;
  sec=0;
  intentSendTime=new Intent();
  
  
  
  //接收线程的信息实现时间递增
  handler=new Handler()
  {
   public void handleMessage(Message msg)
   {
    timeAdd = msg.getData().getBoolean("timeadd");
    //模拟时间变化规律
    if(timeAdd)
    {
     if(sec+1==60)
     {
      if(min+1==60)
      {
       hour++;
       min=0;
      }
      else
      {
       min++;
      }
      sec=0;
     }
     else
     {
      sec++;
     }
    }
    
    intentSendTime.putExtra("hour", hour);
    intentSendTime.putExtra("min", min);
    intentSendTime.putExtra("sec", sec);
    
    intentSendTime.setAction(ACTIONServiceTOActivity);
    sendBroadcast(intentSendTime);
   }
  };
  timecountThread=new Thread(this);
  timecountThread.start();
 }
 
 @Override
 public void onDestroy()
 {
  super.onDestroy();
  unregisterReceiver(serviceReceiver);
 }
 @Override
 public void run()
 {
  flagIfContinnute=true;
  while(flagIfContinnute)
  {
   Message msg = handler.obtainMessage();//每一次都必须新建msg!
   Bundle data = new Bundle();
   data.putBoolean("timeadd", true);
   msg.setData(data);
   handler.sendMessage(msg);
   try
   {
    Thread.sleep(1000);//每隔一秒钟告诉handler时间递增1
   } catch (InterruptedException e)
   {
    e.printStackTrace();
   }
  }
 }
 
 class ServiceReceiver extends BroadcastReceiver
 {
  @Override
  public void onReceive(Context context, Intent intent)
  {
   Bundle bundle1=intent.getExtras();
   boolean temp=bundle1.getBoolean("StartOrNot",true);
   if(!flagIfContinnute&&temp)//本来没有启动线程而Activity告知启动线程,那么就启动
   {
    timecountThread=new Thread(TimeService.this);
    timecountThread.start();
   }
   if(flagIfContinnute&&!temp)//本来已经启动线程而Activity告知停止线程,那么就停止
    flagIfContinnute=false;
  }
 }
}

自定义计时器就是这么简单。。。。

需要源码的留言吧~

© 著作权归作者所有

共有 人打赏支持
龙扬凡
粉丝 0
博文 1
码字总数 1206
作品 0
广州
程序员
加载中

评论(8)

正在前行ay
正在前行ay
1137211202@qq.com,谢谢大好人,这是我的邮箱,可以发一份源码我吗
开发军
445010487@qq.com 请赐源码
h
hxl8811
h2562027@163.com讨教源码
许心炜
许心炜

引用来自“龙扬凡”的评论

http://pan.baidu.com/s/1bngVZBL
方便留个邮箱么 能不能请教点问题 我用了下你的代码 可是bindservice执行后不能执行service的oncreate()方法 导致service不能启动 不知道为什么
龙扬凡
龙扬凡
http://pan.baidu.com/s/1bngVZBL
龙扬凡
龙扬凡

引用来自“龙扬凡”的评论

0

引用来自“许心炜”的评论

哥们 方便把你的工程发给我么 跪求啊 542065452@qq.com 万分感谢
http://pan.baidu.com/s/1bngVZBL 已经上传到网盘了
许心炜
许心炜

引用来自“龙扬凡”的评论

0
哥们 方便把你的工程发给我么 跪求啊 542065452@qq.com 万分感谢
龙扬凡
龙扬凡
0
Chronometer和CountDownTimer计时器

Android小知识10则(上) Android小知识10则(下) Android用5种方式实现自定义计时器, 哪种才是你的菜? github传送门 目录 前言 Chronometer的使用 CountDownTimer的使用 最后 前言 mTimer.set...

Sorrower丶
08/14
0
0
Android 设置合理的定时器隔一段时间执行某段程序

Android 计时器Timer用法 先看段代码,这个实例化了一个Handler,Handler可以通过Message在多个线程通讯,我这里做的是定时recLen加1,然后以一定的格式,显示到recTime上(UI线程上的操作)...

Okimbin
2013/02/23
0
3
Android 倒计时工具CountDownTimer的使用

一、用法详解 在Android开发中,有时需要使用倒计时功能,在Android系统中提供了一个倒计时的抽象类来辅助倒计时行为。 这个类有点缺陷,就是不能暂停后再次接着继续使用,为此,需要自定义一...

IamOkay
2014/11/23
0
0
android中定时-开“关机”的实现

关于android自动关机,网上有很多应用程序和例子。 相对于自动开机来说,自动关机可以在应用层通过设置alarm来实现。而自动开机,它需要底层rtc时钟的支持。我自己也没做过这个,不过在网上查...

雨焰
2013/03/18
0
1
Android 计时器Timer用法

昨天晚上在写一个Android的计时器,开始认为很容易,用Java一般写法,结果发现计时器根本不能运行,但却不报任何错误,当时就呆在那了,不知道该怎么办了,后来在网上查了一下,Android考虑到...

程序袁_绪龙
2014/09/15
0
1

没有更多内容

加载失败,请刷新页面

加载更多

TypeScript基础入门之声明合并(一)

转发 TypeScript基础入门之声明合并(一) 声明合并 介绍 TypeScript中的一些独特概念描述了类型级别的JavaScript对象的形状。 TypeScript特别独特的一个例子是"声明合并"的概念。 在使用现有J...

durban
11分钟前
1
0
Mysql-db

aptitude install default-libmysqlclient-dev pip install mysql-python

dragon_tech
15分钟前
1
0
函数装饰器

def debug(func): def wrapper(*args, **kwargs): # 多个参数# def wrapper(something): # 指定一样的参数 print("[DEBUG]: enter {}()".format(func.__name__)) ......

colin_86
18分钟前
1
0
Notification-状态栏上的通知

当程序并不是出在运行状态的时候,可以调用Notification来显示通知。 1、创建 Notification的创建主要涉及到三个类:NotificationManager,Notification和PendingIntent NotificationManager主...

西米小娅
20分钟前
1
0
Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource c

spring boot启动报错: Description: Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured. Reason: Failed to determin......

wenzhizhon
22分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部