一、问题描述

  Service组件可以实现在后台执行一些耗时任务,甚至可以在程序退出的情况下,让Service在后台继续保持运行状态。Service分本地服务和远程服务,Local地服务附在主进程上的main线程上而不是独立的进程,这样在一定程度上节约了资源;Remote服务占用独立的进程,由于是独立的进程,因此会占用一定的资源但在Activity所在进程被Kill的时候,该服务依然在运行,不受其他进程影响,有利于为多个进程提供服务具有较高的灵活性,一些提供系统服务的Service就是这种常驻的远程服务。

  BroadcastReceiver生命周期短,onReceiver方法必须在10秒内完成,因此将耗时工作可以通过Intent发送给Service,由Service进行处理;广播是Android应用组件间通信的重要手段,例如:我们可以在一个Service中定义一个BroadcastReceiver,在Activity中发送广播,从而实现Activity对Service的控制,我们也可以在一个Activity定义一个BroadcastReceiver,在一个Service中发送广播来操作Activity中的UI,下面我们就通过BroadcastReceiver实现Service与Activity之间的交互实现倒计时功能

运行效果:

二、 编写应用起始界面(ClockActivity)

1、XML文件

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.jerehedu.receiver.ClockActivity">
<TextView android:text="倒计时"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tvTitle"
/>
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/tvTitle"
android:text="02:00:00"
android:textSize="40sp"
android:id="@+id/tvClock"
>
</TextView>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="开始"
android:id="@+id/btStart"
android:layout_below="@+id/tvClock"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:onClick="restart"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="停止"
android:id="@+id/btStop"
android:layout_alignTop="@+id/btStart"
android:layout_centerHorizontal="true"
android:onClick="pause"
/>
</RelativeLayout>

2、代码:

public class ClockActivity extends Activity {
private TextView tvClock;
public static final String CLOCK_ACTION="com.jereh.Clock_Action";
public static int TIME=2*60*60*1000;//倒计时2个小时
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_clock);
tvClock=(TextView)super.findViewById(R.id.tvClock);
regReceiver();//注册广播
startService(new Intent(this,ClockService.class));//启动计时服务
}
@Override
protected void onDestroy() {
super.onDestroy();
super.unregisterReceiver(clockReceiver);
TIME=2*60*60*1000;
Intent intent=new Intent();
intent.setAction(ClockService.CLOCK_SERVICE_ACTION);
intent.putExtra("method", "stop");
super.sendBroadcast(intent);
}
private void regReceiver(){
IntentFilter intentFilter=new IntentFilter();
intentFilter.addAction(CLOCK_ACTION);
super.registerReceiver(clockReceiver, intentFilter);
}
/**
*广播接受者,接受来自ClockService(计时服务)的广播,ClockService每隔一秒
*钟发一次广播
*/
private BroadcastReceiver clockReceiver=new BroadcastReceiver(){
@Override
public void onReceive(Context context, Intent intent) {
changeTime();//改变TextView中的显示时间
}
};
//通过发送广播,控制计时服务
//继续计时
public void restart(View view){
Intent intent=new Intent();
intent.setAction(ClockService.CLOCK_SERVICE_ACTION);
intent.putExtra("method", "continue");
super.sendBroadcast(intent);
}
//通过发送广播,控制计时服务
//暂停计时
public void pause(View view){
Intent intent=new Intent();
intent.setAction(ClockService.CLOCK_SERVICE_ACTION);
intent.putExtra("method","pause");
super.sendBroadcast(intent);
}
private void changeTime(){
String stime="";
if(TIME==0){
stime="计时结束";
}else{
int hour=TIME/(1000*60*60);
int minute=TIME%(1000*60*60)/(60*1000);
int second=(TIME%(1000*60*60))%(60*1000)/1000;
String shour=""+hour,sminute=""+minute,ssecond=""+second;
if(hour<=9){
shour="0"+hour;
}
if(minute<=9){
sminute="0"+minute;
}
if (second<=9){
ssecond="0"+second;
}
stime=shour+":"+sminute+":"+ssecond;
}
tvClock.setText(stime);
} }
三、ClockService组件
public class ClockService extends Service {
public static final String CLOCK_SERVICE_ACTION="clock_service_actoin";
private boolean controllOpt=true;
public ClockService() { }
@Override
public void onCreate(){
IntentFilter intentFilter=new IntentFilter();
intentFilter.addAction(CLOCK_SERVICE_ACTION);
//在service中注册广播(serviceController),接受来自ClockActivity中
//的广播信息,实现对计时服务的控制(暂停、继续)
super.registerReceiver(serviceController,intentFilter);
}
@Override
public int onStartCommand(Intent intent,int flags,int startId){
countTime();//执行计时功能
return Service.START_STICKY;
}
//实现计时功能,每隔一秒减少总时间并ClockActivity发送广播
private void countTime(){
new Thread(new Runnable() {
@Override
public void run() {
Intent intent= Intent(ClockActivity.CLOCK_ACTION);
while(controllOpt){
try {
Thread.sleep(1000);
if(ClockActivity.TIME<=0){
sendBroadcast(intent);
stopSelf();
break;
}
ClockActivity.TIME-=1000;
sendBroadcast(intent);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
//广播接受者,接受来自ClockActivity的广播以便暂停、继续、停止广播
private BroadcastReceiver serviceController=new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String method=intent.getStringExtra("method");
switch (method){
case "pause":
controllOpt=false;
break;
case "continue":
controllOpt=true;
countTime();
break;
case "stop":
controllOpt=false;
stopSelf();
break;
}
}
};
@Override
public IBinder onBind(Intent intent) {
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public void onDestroy(){
super.unregisterReceiver(serviceController);
}
}
作者:杰瑞教育
出处:http://www.cnblogs.com/jerehedu/ 
版权声明:本文版权归烟台杰瑞教育科技有限公司和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

技术咨询:
 

Android四大组件应用系列——使用BroadcastReceiver和Service实现倒计时的更多相关文章

  1. Android四大组件应用系列5——使用AIDL实现跨进程调用Service

    一.问题描述 Android应用程序的四大组件中Activity.BroadcastReceiver.ContentProvider.Service都可以进行跨进程.在上一篇我们通过ContentPr ...

  2. Android四大组件应用系列——实现电话拦截和电话录音

    一.问题描述 使用BordercastReceiver和Service组件实现下述功能: 1.当手机处于来电状态,启动监听服务,对来电进行监听录音. 2.设置电话黑名单,当来电是黑名单电话,则直接挂断 ...

  3. Android四大组件应用系列——Activity与Service交互实现APK下载

    Servic与Activity相比它没有界面,主要是在后台执行一些任务,Service有两种启动方法startService()和bindService(),startService方式Service ...

  4. Android四大组件应用系列——使用ContentProvider实现跨进程通讯

    一.问题描述 如何在Android中实现不同应用之间的通讯(既跨进程进行调用)?Android提供了多种实现方式,使我们可以实现跨进程访问Activity.通过ContentProvider跨进程访问 ...

  5. Android四大组件之——Activity的生命周期(图文详解)

        转载请在文章开头处注明本博客网址:http://www.cnblogs.com/JohnTsai       联系方式:JohnTsai.Work@gmail.com       [Andro ...

  6. Android四大组件之——Activity的开启:StartActivity()和StartActivityForResult()(图文详解)

                如需转载请在文章开头处注明本博客网址:http://www.cnblogs.com/JohnTsai       联系方式:JohnTsai.Work@gmail.com   ...

  7. Android四大组件之——ContentProvider(一)

    Android四大组件之--ContentProvider(一) 本人邮箱:JohnTsai.Work@gmail.com,欢迎交流讨论. 欢迎转载,转载请注明网址:http://www.cnblog ...

  8. [置顶] Android四大组件之BroadcastReceiver

    Android四大组件之BroadcastReceiver Broadcast Receiver 广播接收器,是一种负责接收广播消息并对消息做出响应的组件,和Service一样并不提供与用户交互的UI ...

  9. Android 四大组件之“ BroadcastReceiver ”

    前言 Android四大组件重要性已经不言而喻了,今天谈谈的是Android中的广播机制.在我们上学的时候,每个班级的教室里都会装有一个喇叭,这些喇叭都是接入到学校的广播室的,一旦有什么重要的通知,就 ...

随机推荐

  1. Java中BigDecimal类介绍及用法

    Java中提供了大数字(超过16位有效位)的操作类,即 java.math.BinInteger 类和 java.math.BigDecimal 类,用于高精度计算. 其中 BigInteger 类是 ...

  2. MySQL表的定期分析检查优化

    Analyze Table 分析表   MySQL 的Optimizer(优化元件)在优化SQL语句时,首先需要收集一些相关信息,其中就包括表的cardinality(可以翻译为“散列程度”),它表示 ...

  3. 双线程 线性dp 传纸条

    /* 两种做法:一是暴力dp[i][j][k][l] 二是以走的步数k作为阶段, dp[k][i][j]表示走到第k步,第一个人横坐标走到i,第二个人横坐标走到j 可以以此推出第第一个人的坐标为[i, ...

  4. SPLAY,LCT学习笔记(一)

    写了两周数据结构,感觉要死掉了,赶紧总结一下,要不都没学明白. SPLAY专题: 例:NOI2005 维修数列 典型的SPLAY问题,而且综合了SPLAY常见的所有操作,特别适合新手入门学习(比如我这 ...

  5. mysql undo 和redo 被误删除的恢复操作(一致性)

    今天在群里看到有人说不熟悉innodb把ibdata(数据文件)和ib_logfile(事务日志)文件误删除了.不知道怎么解决.当时我也不知道怎么办.后来查阅相关资料.终找到解决方法.其实恢复也挺简单 ...

  6. BZOJ1202 [HNOI2005]狡猾的商人 spfa

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1202 题意概括 有一个数列,共n个数字. 告诉你m个区间和,问是否矛盾. 数据组数<=100 ...

  7. 6-8 树 uva548

    read 的方式值得学习 当不知道每一行有多少个输入的时候 getline  在弄成stringstream!一个一个处理 用built递归的方式化大为小进行建立树 dfs 遍历整个树来求最值 变量的 ...

  8. 键盘键码Key Code

    来源:https://www.cambiaresearch.com/articles/15/javascript-char-codes-key-codes Key Code backspace 8 t ...

  9. hdu 3466 Proud Merchants 【限制性01背包】+【贪心】

    题目链接:https://vjudge.net/contest/103424#problem/J 转载于:https://www.bbsmax.com/A/RnJW16GRdq/ 题目大意: 有n个商 ...

  10. MySql:Table 'database.TABLE_ONE' doesn't exist

    1. 问题描述 由于最近使用本地的MySQL奔溃了,在修改管理员密码时,不慎修改错误,导致无法重新写会,甚至按照MySQL官网手册都无法修改正确,遂放弃修改root密码,直接将一个未有数据的纯净版My ...