Android四大组件应用系列——使用BroadcastReceiver和Service实现倒计时

一、问题描述

  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/ 
版权声明:本文版权归烟台杰瑞教育科技有限公司和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

技术咨询:

时间: 2024-10-23 22:33:11

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

android四大组件之广播接收器BroadcastReceiver

Android有一个非常重要的特性,就是广播.也可以将广播看做是通信机制.  Android四大组件: Activity, service, broadcastReceiver 和contentProvider, 只有Activity和service有完整的生命周期, 其他 broadcastReceiver 和contentProvider 都没有.  broadcastReceiver 本质上是一个监听器, 负责监听系统应用发出的广播(BroadCast). broadcastReceive

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

一.问题描述 使用BordercastReceiver和Service组件实现下述功能: 1.当手机处于来电状态,启动监听服务,对来电进行监听录音. 2.设置电话黑名单,当来电是黑名单电话,则直接挂断. 当拨打电话或电话状态发生改变时,系统就会发出有序广播,因此我们可以使用BordercastReceiver接受广播,因BordercastReceiver执行时间短不能执行耗时任务也不能使用子线程,因此我们应启动一个Service来监听电话并进行处理 二.加入AIDL文件 Android没有对外

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

一.问题描述 如何在Android中实现不同应用之间的通讯(既跨进程进行调用)?Android提供了多种实现方式,使我们可以实现跨进程访问Activity.通过ContentProvider跨进程访问其他应用的数据.通过Broadcast可以向android系统中所有应用程序发送广播.使用AIDL实现跨进程的Service.下面我们就使用ContentProvider实现跨进程访问数据,并可对数据进行增.删.改.查 二.应用实现 使用ContentProvider实现数据共享,主要是共享应用的S

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

Servic与Activity相比它没有界面,主要是在后台执行一些任务,Service有两种启动方法startService()和bindService(),startService方式Service不可交互,可一直在后台即便应用结束,bindService方式可通过ServiceConnection获得运行的Service实例的方式实现Activity和Service之间的交互,通常Activity退出则绑定的服务也就取消了.我们可以通过同时执行启动服务和绑定服务的方式实现Service交互同

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

            如需转载请在文章开头处注明本博客网址:http://www.cnblogs.com/JohnTsai       联系方式:[email protected]       [Android四大组件学习系列Activity篇]        1.Android四大组件之——Activity(一)定义.状态和后退栈(图文详解) 2.Android四大组件之——Activity的生命周期(图文详解) 3.Android四大组件之——Activity的开启StartActivit

Android四大组件之BroadcastReceiver详细解析

什么是BroadcastReceiver? BroadcastReceiver作为Android四大组件之一,在实际开发中也发挥着重要的作用,广播机制在Android程序通信中至关重要,广播其实与我们现实生活中的电台很相似,电台在某个频道上发送它的内容,那么只要有在收听这个频道的人都会收到这些内容.在Android中,广播也同样分为两个角色:广播发送者.广播接收者. BroadcastReceiver的应用场景 1.在一个应用中,我们的Activity与Service的通信就需要用到广播来作为中

Android 四大组件 (三) BroadcastReceiver 介绍

一. BroadcastReceiver 使用场景 Broadcast主要是用作消息通信(专业术语叫IPC),Android的IPC基本都是binder来实现,那么这里的BroadcastReceiver其实也是对binder的一个封装,方便上层调用.开发过程中遇到的单进程多线程通信的场景比较多,所以这种情况下使用Broadcast并不是最佳选择,很多人会自己实现一套 Observer 或者使用EventBus等第三方库来完成该功能,不可否认,他们在这种场合下不论是效率还是灵活性方面都更具优势.

Android四大组件--Activity详解

Android四大组件--Activity详解 分类: android android应用android开发 本文的主要内容包括1.activity的建立.配置和使用:2.activity的跳转和传值:3.startActivityForResult:4.activity的生命周期. 1.activity的建立.配置和使用 Activity是一个应用中的组件,它为用户提供一个可视的界面,方便用户操作,比如说拔打电话.照相.发邮件或者是浏览地图等.每个activity会提供一个可视的窗口,一般情况

Android 四大组件 详解

[置顶] Android四大组件详解 分类: Android四大组件2013-02-09 16:23 19411人阅读 评论(13) 收藏 举报 Android开发 注:本文主要来自网易的一个博主的文章,经过阅读,总结,故留下文章在此 Android四大基本组件介绍与生命周期 Android四大基本组件分别是Activity,Service服务,Content Provider内容提供者,BroadcastReceiver广播接收器. 一:了解四大基本组件 Activity : 应用程序中,一个