星期二, 9月 20, 2011

繼承IntentService實作started service

Android應用程式學習筆記

繼承IntentService實作started service

之前已學習到started service有兩種實現方式,一種是繼承IntentService類別,另一種是繼承Service類別,今天就來實現一下繼承IntentService的started service。

1.首先開啟新專案HelloIntentService
2.main.xml產生兩個按鈕,一個是啟動service,一個是停止service
3.HelloIntentService的activity執行按鈕按下啟動service及停止service

啟動service:

Intent intent = new Intent(this , HelloIntentService.class);
    startService(intent);
停止service:

Intent intent = new Intent(this , HelloIntentService.class);
    stopService(intent);



4.在HelloIntentService/src目錄下新增.java文件


package test.hellointentservice;

import android.app.IntentService;
import android.content.Intent;
import android.os.IBinder;

public class HelloIntentService extends IntentService {

public HelloIntentService(){
super("IntentService");
}

//當service第一次被啟動時,系統第一個呼叫此方法,接著才會呼叫其他方法。
@Override
public void onCreate(){
super.onCreate();
System.out.println("Service--------->onCreate");
System.out.println("thread-------->" + Thread.currentThread().getId());
}

@Override
public void onStart(Intent intent , int startId){
super.onStart(intent, startId);
System.out.println("Service------->onStart");
System.out.println("thread-------->" + Thread.currentThread().getId());
}

@Override
protected void onHandleIntent(Intent intent){
System.out.println("Service--------->onHandleIntent");
System.out.println("intent.flag--------->" + intent.getFlags());
System.out.println("thread-------->" + Thread.currentThread().getId());
long endTime = System.currentTimeMillis() + 10*1000;
     while (System.currentTimeMillis() < endTime) {
         synchronized (this) {
             try {
                 wait(endTime - System.currentTimeMillis());
             } catch (Exception e) {
             }
         }
     }
}
//started形式的service所必須複寫的方法,組件呼叫startService()方法後,系統會自動呼叫此方法。
@Override
public  int onStartCommand(Intent intent , int flags , int startId){
System.out.println("service--------->onStartCommand");
System.out.println("thread-------->" + Thread.currentThread().getId());
return super.onStartCommand(intent, flags, startId);
}
//bound形式的service必須複寫的方法
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
System.out.println("Service---->onBind");
return null;
}
//當service銷毀時呼叫此方法。
@Override
public void onDestroy(){
super.onDestroy();
System.out.println("Service------->onDestroy");
}
}

IntentService執行時會產生新的thread來完成工作,因此我們就來試試是否如此。在每個方法都加上System.out.println("thread-------->" + Thread.currentThread().getId())來看看現在是哪一個執行續。
其中也要注意,我們之前說過能複寫onCreate()、onDestroy()、onStartCommand()等方法,但唯有onBind()方法不需要呼叫super類別,所以我們在複寫時都有加上super.類別。

執行結果如下

從中可以發現activity啟動intentservice的順序。
activity呼叫startService()啟動service ---> 系統呼叫onCreate()產生新的執行續 ---> 系統呼叫onStartCommand() ---> 呼叫onStart(),傳遞intent物件到onHanldeIntent() ---> 呼叫onHandleIntent(),執行service工作 ---> 工作完成,service銷毀,呼叫onDestroy()。

因為service第一次啟動,所以會先呼叫onCreate()方法。
給service執行的工作放在onHandleIntent()方法中。

另外你可以試試,在service工作還沒完成之前把activity關閉,看看service是不是會受到影響。
那我們發現是不會的,activity關閉後,service並沒有因此停止,而是繼續執行直到工作完成。

1 則留言:

  1. 拜讀7年前文章

    您好,想請教一下
    如果收到boardcast將收到的通知標題內容送出 丟給intentService工作
    intentService做的是將標題內容做成一張圖片,並透過藍芽送出
    請問是把相關功能全部放在onHandleIntent()裡面嗎

    原本是在Activity的oncreate裡面傳送圖片,雖然可以傳送,但發現整個Activity傳完為止都會卡住

    回覆刪除