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技術交流
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM