zoukankan      html  css  js  c++  java
  • 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/ 
    版权声明:本文版权归杰瑞教育技有限公司和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
    技术咨询:JRedu技术交流
     
  • 相关阅读:
    Python 集合
    Python 文字列
    JUNIT5(maven配置)
    Javascript严格模式
    移动互联测试
    Python的基础知识
    Linux系统下发件oa环境
    禅道的使用
    Linux系统的安装过程
    Oracle基础知识
  • 原文地址:https://www.cnblogs.com/jerehedu/p/4885259.html
Copyright © 2011-2022 走看看