而為何要在service裡面建立另一個不斷執行的執行緒呢?因為雖然service會常駐在os裡面,但卻不會反覆執行。這樣需要反覆執行的能力常常會用在背景同步資料、向網路驗證資料等。service因為沒有UI,很難判定到底是否有執行,所以底下的程式會用Log的方式於主控台中輸出資料。而以下的程式是使用startService()這個方法,此方法適用於service與activity之間不需互相調用任何參數的情況。若activity與service之間有參數互相傳遞的話,要使用bindService()這個方法,並用onBind()來啟動service。bindService()的實作範例之後再介紹。
public class NotificationService extends Service {
//建立Handler物件,作為執行緒傳遞 postDelayed之用
private Handler objHandler = new Handler();
//為了確認系統服務執行情況
private int intCounter=0;
//成員變數checkNotification為Runnable物件,作為Timer之用
private Runnable checkNotification = new Runnable() {
public void run(){
intCounter++;
Log.i("TEST", "Counter:"+Integer.toString(intCounter));
//每1秒呼叫Handler.postDelayed方法反覆執行
objHandler.postDelayed(checkNotification, 1000);
}
};
@Override
public void onCreate(){
//服務開始,即呼叫每1秒呼叫mTasks執行緒
//objHandler.postDelayed(checkNotification, 1000);
super.onCreate();
}
@Override
public void onStart(Intent intent, int startId){
// TODO Auto-generated method stub
super.onStart(intent, startId);
}
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public void onDestroy(){
//當服務結束,移除checkNotification執行緒
objHandler.removeCallbacks(checkNotification);
super.onDestroy();
}
}
而在activity的程式,只需在onCreate()裡呼叫startService()來啟動這支service程式即可在主控台中看到log的產生。
public class ActivityService extends Activity{
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
/* 建構Intent物件,指定開啟對象為NotificationService服務 */
Intent i = new Intent(ActivityService.this, NotificationService.class );
/* 設定新TASK的方式 */
i.setFlags( Intent.FLAG_ACTIVITY_NEW_TASK );
/* 以startService方法啟動Intent */
startService(i);
}
}
覺得在主控台輸出Log的service讓你沒有fu嗎?沒關係,我們增加一個Notification,讓程式可以隨時在StatusBar被啟動。
將NotificationService.java修改為以下程式碼:
public class NotificationService extends Service {
//建立Handler物件,作為執行緒傳遞 postDelayed之用
private Handler objHandler = new Handler();
//建立Notification
private NotificationManager notifyIcon ;
//為了確認系統服務執行情況
private int intCounter=0;
//成員變數checkNotification為Runnable物件,作為Timer之用
private Runnable checkNotification = new Runnable() {
public void run(){
intCounter++;
Log.i("TEST", "Counter:"+Integer.toString(intCounter));
//每1秒呼叫Handler.postDelayed方法反覆執行
objHandler.postDelayed(checkNotification, 1000);
//Notification Icon on the status bar
notifyIcon = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
showNotification();
}
};
@Override
public void onCreate(){
//服務開始,即呼叫每1秒呼叫mTasks執行緒
objHandler.postDelayed(checkNotification, 1000);
super.onCreate();
}
@Override
public void onStart(Intent intent, int startId){
// TODO Auto-generated method stub
super.onStart(intent, startId);
}
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public void onDestroy(){
//當服務結束,移除checkNotification執行緒
objHandler.removeCallbacks(checkNotification);
super.onDestroy();
}
private void showNotification(){
Notification notification = new Notification(R.drawable.icon,"Service started", System.currentTimeMillis());
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, ActivityService.class), 0);
// must set this for content view, or will throw a exception
notification.setLatestEventInfo(this, "Test Service", "Service started",contentIntent);
notifyIcon.notify(R.string.test, notification);
}
}
0 comments:
Post a Comment