一、問題描述 |
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/
版權聲明:本文版權歸煙 台 傑瑞教育 科 技有限公司和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。
技術咨詢:
出處: http://www.cnblogs.com/jerehedu/
版權聲明:本文版權歸煙 台 傑瑞教育 科 技有限公司和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。
技術咨詢:
