本篇將介紹Service的初步應用,利用Button來開始或取消Service的動作。
Service,可用於後台執行的程式,可不開啟Activity,並執行一些動作,如網路上下載、音樂撥放等等...通常可再搭配Notify功能,當Service完成某項任務時,利用Notify可彈出提醒視窗。而Service又分為綁定型與非綁定型Service,其綁定型需依附於Activity,如果Activity終止,則Service也會終止,非綁定的則否。本篇則是以非綁定Service做範例。
圖為一個非綁定型Service的Lifecycle,當啟用開Service時,需調用stopService()才能使該Service進入onDestroy()內終止該Service。
以下將示範利用一個Activity介面,點擊Button開始Service或停止Service,由於此示範為獨立式Service非綁定式Service,因此在Start Service後,關閉應用程式,Service依然在背景上執行,需再開啟應用程式將其Service stop才可停止。
private Intent samIntent;
private Button startbtn,stopbtn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
samIntent=new Intent(MainActivity.this,samService.class); //使用Intent,由MainActivity對SamService
startbtn=(Button)findViewById(R.id.startbtnID);
stopbtn=(Button)findViewById(R.id.stopbtnID);
startbtn.setOnClickListener(new btnclicklistener());
stopbtn.setOnClickListener(new btnclicklistener());
}
首先將所需的Button與 Intent定義出來,開啟Service的方式需建立一個Intent來開啟,以上綁定ID與Click綁定後,接著再ClickListener內加入以下
class btnclicklistener implements View.OnClickListener{
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.startbtnID:
startService(samIntent);
break;
case R.id.stopbtnID:
stopService(samIntent);
break;
}
}
}
onClick內判斷是否為Start Button或Stop Button,並使用startService(Intent)或stopService(Intent)來開啟Service或關閉Service。
接著再另外新增一個Class如下圖
,並繼承於Service ,接著建立一個Handler給要呼叫Runnable時使用,並建立一個Runnable 名為 showTime,其function會Log出目前的時間
public class samService extends Service{
private Handler handler1=new Handler();
private Runnable showTime=new Runnable() {
@Override
public void run() {
Log.i("mylog",new Date().toString()); //Log出目前時間
handler1.postDelayed(this,1000); //使此Runnable每1秒重Run一次
}
};
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate(){
Log.i("samLog","Enter onCreate()");
super.onCreate();
Log.i("samLog", "Leave onCreate()");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("samLog","Enter onStartCommand()");
handler1.post(showTime); //開啟此Service時,執行showTime
return Service.START_STICKY; //一個返回值,如果此Service被異常終止時,將嘗試重新開啟此Service
}
@Override
public void onDestroy() { //除非調用stopService(),否則不會進入此區塊
Log.i("samLog","Enter onDestroy()");
super.onDestroy();
handler1.removeCallbacks(showTime); //利用removeCallbacks()停止handler.post(showTime)
Log.i("samLog","Leave onDestroy()");
}
}
接著在onStartCommand內使用handler1.post(showTime)啟用Runnable,其中onStartCommand內的 return Service.START_STICKY,當該Service被異常刪除時,將會重新啟動該Service,
因此除非調用stopService(),否則該Service將不會進到 onDestroy()區塊。