IntentService是什麼?
IntentService是Service的一種,使用上較為方便簡單。其背景執行方式是透過 HandleThread,因此單個IntentService上的任務是循序執行的,可以保證執行緒安全。不同的IntentService在執行上也不會互相干擾。
IntentService適合用於客戶端不須和Service互動的情況下,基本上由客戶端呼叫startService並指定啟動的IntentService。
簡單的IntentService實作
public class SimpleIntentService extends IntentService {  
    
    public SimpleIntentService() {  
      super("SimpleIntentService");  
    }  
    
    @Override  
    protected void onHandleIntent(Intent intent) {  
    }  
    
  }  
    onHandleIntent方法會執行在新的執行緒上,也是放置耗時操作的位置。其參數intent就是從客戶端傳遞過來的intent。
另外需要在AndroidManifest.xml宣告該IntentService
<service
android:exported="false"
android:name=".simpleintentservice.SimpleIntentService">
</service>
android:exported="false"代表是否可以由其他的App啟動。
啟動IntentService
客戶端透過呼叫startService方法來啟動IntentService
public class SimpleIntentServiceActivity extends AppCompatActivitye {  
    
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
      super.onCreate(savedInstanceState);  
      setContentView(R.layout.activity_simple_intent_service);  
    
      Intent launchSimpleIntentService = new Intent(this, SimpleIntentService.class);  
      startService(launchSimpleIntentService);  
    }  
  }  
    
    客戶端傳遞資料到IntentService
從客戶端透過intent放置資料便可傳遞到IntentService
Intent launchSimpleIntentService = new Intent(this, SimpleIntentService.class);
launchSimpleIntentService.putExtra("data", "data from activity");
startService(launchSimpleIntentService);
透過IntentService的onHandleIntent的參數取出資料
@Override
protected void onHandleIntent(Intent intent) {
String data = intent.getStringExtra("data");
Log.d(TAG, "data:" + data);
}
output:
D: data:data from activity
IntentService的生命週期
複寫IntentService的生命週期方法觀察呼叫順序
public class SimpleIntentService extends IntentService {  
    
    private static final String TAG = SimpleIntentService.class.getSimpleName();  
    
    public SimpleIntentService() {  
      super("SimpleIntentService");  
      Log.d(TAG, "SimpleIntentService: ");  
    }  
    
    @Override  
    public void onCreate() {  
      super.onCreate();  
      Log.d(TAG, "onCreate: ");  
    }  
    
    @Override  
    public void onDestroy() {  
      super.onDestroy();  
      Log.d(TAG, "onDestroy: ");  
    }  
    
    @Override  
    public int onStartCommand(@Nullable Intent intent, int flags, int startId) {  
      Log.d(TAG, "onStartCommand: ");  
      return super.onStartCommand(intent, flags, startId);  
    }  
    
    @Override  
    protected void onHandleIntent(Intent intent) {  
      Log.d(TAG, "onHandleIntent: ");  
      String data = intent.getStringExtra("data");  
      Log.d(TAG, "data:" + data);  
    }  
    
  }  
    
    Client call
Intent launchSimpleIntentService = new Intent(this, SimpleIntentService.class);
launchSimpleIntentService.putExtra("data", "data from activity");
startService(launchSimpleIntentService);
Log.d(TAG, "startService");
Output
D/SimpleIntentServiceActivity: startService
D/SimpleIntentService: SimpleIntentService:
D/SimpleIntentService: onCreate:
D/SimpleIntentService: onStartCommand:
D/SimpleIntentService: onHandleIntent:
D/SimpleIntentService: data:data from activity
D/SimpleIntentService: onDestroy:
從Output觀察IntentService生命週期的順序為
建構式 -> onCreate -> onStartCommand -> onHandleIntent -> onDestroy
客戶端停止IntentService
透過呼叫stopService()方法來停止IntentService。
Intent stopSimpleIntentService = new Intent(this, SimpleIntentService.class);
stopService(stopSimpleIntentService);
Log.d(TAG, "stopService");
傳入的Intent必須指定要停止的IntentService。
呼叫StopService之後,IntentService便會呼叫onDestroy方法銷毀自己。
需要注意的是因為onHandleIntent方法內部是由新的執行緒來執行,因此即使是客戶端呼叫了stopService,但是onHandleIntent方法不會結束。
為了測試這點在onHandleIntent方法加入計時10秒的操作
@Override
protected void onHandleIntent(Intent intent) {
Log.d(TAG, "onHandleIntent: ");
String data = intent.getStringExtra("data");
Log.d(TAG, "data:" + data);
sleep(10);
}
private void sleep(int sleepTimeSeconds) {
for (int i = 0; i < sleepTimeSeconds; ++i) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.d(TAG, "sleep: "+i);
}
}
客戶端並在第3秒呼叫stopService
Output如下
D/SimpleIntentServiceActivity: startService
D/SimpleIntentService: SimpleIntentService:
D/SimpleIntentService: onCreate:
D/SimpleIntentService: onStartCommand:
D/SimpleIntentService: onHandleIntent:
D/SimpleIntentService: data:data from activity
D/SimpleIntentService: sleep: 0
D/SimpleIntentService: sleep: 1
D/SimpleIntentService: sleep: 2
D/SimpleIntentService: sleep: 3
D/SimpleIntentServiceActivity: stopService
D/SimpleIntentService: onDestroy:
D/SimpleIntentService: sleep: 4
D/SimpleIntentService: sleep: 5
D/SimpleIntentService: sleep: 6
D/SimpleIntentService: sleep: 7
D/SimpleIntentService: sleep: 8
D/SimpleIntentService: sleep: 9
可以看到即使IntentService已經銷毀了,但計時仍然繼續。
因此若要呼叫stopService也一併停止onHandleIntent的內容,可以建立成員變數來控制是否要停止計時,如下
private boolean mIsDestroy;
@Override
public void onDestroy() {
mIsDestroy = true;
super.onDestroy();
Log.d(TAG, "onDestroy: ");
}
private void sleep(int sleepTimeSeconds) {
for (int i = 0; i < sleepTimeSeconds && !mIsDestroy; ++i) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.d(TAG, "sleep: "+i);
}
}
IntentService的循序
IntentService在單一執行緒上執行任務,若客戶端呼叫多次startService方法,IntentService也會保持等待當前的任務完成後再執行下一個任務。
修改印出耗時資訊時也印出IntentService toString
  private void sleep(int sleepTimeSeconds) {  
      for (int i = 0; i < sleepTimeSeconds && !mIsDestroy; ++i) {  
        try {  
          Thread.sleep(1000);  
        } catch (InterruptedException e) {  
          e.printStackTrace();  
        }  
        Log.d(TAG, "sleep: "+i+" name:"+toString());  
      }  
    }  
    連續啟動3次IntentService,Outout如下
D/SimpleIntentService: SimpleIntentService:
D/SimpleIntentService: onCreate:
D/SimpleIntentService: onStartCommand:
D/SimpleIntentService: onHandleIntent:
D/SimpleIntentService: data:data from activity
D/SimpleIntentService: onStartCommand:
D/SimpleIntentService: onStartCommand:
D/SimpleIntentService: sleep: 0 name:com.codefoxx.serviceexample.simpleintentservice.SimpleIntentService@369cf9c
D/SimpleIntentService: sleep: 1 name:com.codefoxx.serviceexample.simpleintentservice.SimpleIntentService@369cf9c
D/SimpleIntentService: sleep: 2 name:com.codefoxx.serviceexample.simpleintentservice.SimpleIntentService@369cf9c
D/SimpleIntentService: sleep: 3 name:com.codefoxx.serviceexample.simpleintentservice.SimpleIntentService@369cf9c
D/SimpleIntentService: sleep: 4 name:com.codefoxx.serviceexample.simpleintentservice.SimpleIntentService@369cf9c
D/SimpleIntentService: sleep: 5 name:com.codefoxx.serviceexample.simpleintentservice.SimpleIntentService@369cf9c
D/SimpleIntentService: sleep: 6 name:com.codefoxx.serviceexample.simpleintentservice.SimpleIntentService@369cf9c
D/SimpleIntentService: sleep: 7 name:com.codefoxx.serviceexample.simpleintentservice.SimpleIntentService@369cf9c
D/SimpleIntentService: sleep: 8 name:com.codefoxx.serviceexample.simpleintentservice.SimpleIntentService@369cf9c
D/SimpleIntentService: sleep: 9 name:com.codefoxx.serviceexample.simpleintentservice.SimpleIntentService@369cf9c
D/SimpleIntentService: onHandleIntent:
D/SimpleIntentService: data:data from activity
D/SimpleIntentService: sleep: 0 name:com.codefoxx.serviceexample.simpleintentservice.SimpleIntentService@369cf9c
D/SimpleIntentService: sleep: 1 name:com.codefoxx.serviceexample.simpleintentservice.SimpleIntentService@369cf9c
D/SimpleIntentService: sleep: 2 name:com.codefoxx.serviceexample.simpleintentservice.SimpleIntentService@369cf9c
D/SimpleIntentService: sleep: 3 name:com.codefoxx.serviceexample.simpleintentservice.SimpleIntentService@369cf9c
D/SimpleIntentService: sleep: 4 name:com.codefoxx.serviceexample.simpleintentservice.SimpleIntentService@369cf9c
D/SimpleIntentService: sleep: 5 name:com.codefoxx.serviceexample.simpleintentservice.SimpleIntentService@369cf9c
D/SimpleIntentService: sleep: 6 name:com.codefoxx.serviceexample.simpleintentservice.SimpleIntentService@369cf9c
D/SimpleIntentService: sleep: 7 name:com.codefoxx.serviceexample.simpleintentservice.SimpleIntentService@369cf9c
D/SimpleIntentService: sleep: 8 name:com.codefoxx.serviceexample.simpleintentservice.SimpleIntentService@369cf9c
D/SimpleIntentService: sleep: 9 name:com.codefoxx.serviceexample.simpleintentservice.SimpleIntentService@369cf9c
D/SimpleIntentService: onHandleIntent:
D/SimpleIntentService: data:data from activity
D/SimpleIntentService: sleep: 0 name:com.codefoxx.serviceexample.simpleintentservice.SimpleIntentService@369cf9c
D/SimpleIntentService: sleep: 1 name:com.codefoxx.serviceexample.simpleintentservice.SimpleIntentService@369cf9c
D/SimpleIntentService: sleep: 2 name:com.codefoxx.serviceexample.simpleintentservice.SimpleIntentService@369cf9c
D/SimpleIntentService: sleep: 3 name:com.codefoxx.serviceexample.simpleintentservice.SimpleIntentService@369cf9c
D/SimpleIntentService: sleep: 4 name:com.codefoxx.serviceexample.simpleintentservice.SimpleIntentService@369cf9c
D/SimpleIntentService: sleep: 5 name:com.codefoxx.serviceexample.simpleintentservice.SimpleIntentService@369cf9c
D/SimpleIntentService: sleep: 6 name:com.codefoxx.serviceexample.simpleintentservice.SimpleIntentService@369cf9c
D/SimpleIntentService: sleep: 7 name:com.codefoxx.serviceexample.simpleintentservice.SimpleIntentService@369cf9c
D/SimpleIntentService: sleep: 8 name:com.codefoxx.serviceexample.simpleintentservice.SimpleIntentService@369cf9c
D/SimpleIntentService: sleep: 9 name:com.codefoxx.serviceexample.simpleintentservice.SimpleIntentService@369cf9c
D/SimpleIntentService: onDestroy:
可以看到每個任務都必須等到上一個任務完成後才執行。
不同IntentService執行
觀察不同的IntentService執行的情況
新增另一個IntentService為AnotherSimpleIntentService如下
public class AnotherSimpleIntentService extends IntentService {  
    
    private static final String TAG = AnotherSimpleIntentService.class.getSimpleName();  
    
    private boolean mIsDestroy;  
    
    public AnotherSimpleIntentService() {  
      super("AnotherSimpleIntentService");  
      Log.d(TAG, "AnotherSimpleIntentService: ");  
    }  
    
    @Override  
    public void onCreate() {  
      super.onCreate();  
      Log.d(TAG, "onCreate: ");  
    }  
    
    @Override  
    public void onDestroy() {  
      mIsDestroy = true;  
      super.onDestroy();  
      Log.d(TAG, "onDestroy: ");  
    }  
    
    @Override  
    public int onStartCommand(@Nullable Intent intent, int flags, int startId) {  
      Log.d(TAG, "onStartCommand: ");  
      return super.onStartCommand(intent, flags, startId);  
    }  
    
    @Override  
    protected void onHandleIntent(Intent intent) {  
      Log.d(TAG, "onHandleIntent: ");  
      String data = intent.getStringExtra("data");  
      Log.d(TAG, "data:" + data);  
      sleep(10);  
    }  
    
    private void sleep(int sleepTimeSeconds) {  
      for (int i = 0; i < sleepTimeSeconds && !mIsDestroy; ++i) {  
        try {  
          Thread.sleep(1000);  
        } catch (InterruptedException e) {  
          e.printStackTrace();  
        }  
        Log.d(TAG, "sleep: "+i+" name:"+toString());  
      }  
    }  
    
  }  
    AndroidManifest.xml宣告AnotherSimpleIntentService
<service
android:exported="false"
android:name=".simpleintentservice.AnotherSimpleIntentService">
</service>
在客戶端依序啟動SimpleIntentService和AnotherSimpleIntentService
  public void onClick(View view) {  
      int uiID = view.getId();  
      switch (uiID) {  
        case R.id.start_intent_service:  
          startSimpleIntentService();  
          startAnotherSimpleIntentService();  
          break;  
      }  
    }  
    
    private void startAnotherSimpleIntentService() {  
      Intent launchAnotherSimpleIntentService = new Intent(this, AnotherSimpleIntentService.class);  
      launchAnotherSimpleIntentService.putExtra("data", "data from activity");  
      startService(launchAnotherSimpleIntentService);  
      Log.d(TAG, "startService");  
    }  
    
    private void startSimpleIntentService() {  
      Intent launchSimpleIntentService = new Intent(this, SimpleIntentService.class);  
      launchSimpleIntentService.putExtra("data", "data from activity");  
      startService(launchSimpleIntentService);  
      Log.d(TAG, "startService");  
    }  
    Output如下
D/SimpleIntentServiceActivity: startService
D/SimpleIntentServiceActivity: startService
D/SimpleIntentService: SimpleIntentService:
D/SimpleIntentService: onCreate:
D/SimpleIntentService: onStartCommand:
D/SimpleIntentService: onHandleIntent:
D/SimpleIntentService: data:data from activity
D/AnotherSimpleIntentService: AnotherSimpleIntentService:
D/AnotherSimpleIntentService: onCreate:
D/AnotherSimpleIntentService: onStartCommand:
D/AnotherSimpleIntentService: onHandleIntent:
D/AnotherSimpleIntentService: data:data from activity
D/SimpleIntentService: sleep: 0 name:com.codefoxx.serviceexample.simpleintentservice.SimpleIntentService@ff71da5
D/AnotherSimpleIntentService: sleep: 0 name:com.codefoxx.serviceexample.simpleintentservice.AnotherSimpleIntentService@9de157a
D/SimpleIntentService: sleep: 1 name:com.codefoxx.serviceexample.simpleintentservice.SimpleIntentService@ff71da5
D/AnotherSimpleIntentService: sleep: 1 name:com.codefoxx.serviceexample.simpleintentservice.AnotherSimpleIntentService@9de157a
D/SimpleIntentService: sleep: 2 name:com.codefoxx.serviceexample.simpleintentservice.SimpleIntentService@ff71da5
D/AnotherSimpleIntentService: sleep: 2 name:com.codefoxx.serviceexample.simpleintentservice.AnotherSimpleIntentService@9de157a
D/SimpleIntentService: sleep: 3 name:com.codefoxx.serviceexample.simpleintentservice.SimpleIntentService@ff71da5
D/AnotherSimpleIntentService: sleep: 3 name:com.codefoxx.serviceexample.simpleintentservice.AnotherSimpleIntentService@9de157a
D/SimpleIntentService: sleep: 4 name:com.codefoxx.serviceexample.simpleintentservice.SimpleIntentService@ff71da5
D/AnotherSimpleIntentService: sleep: 4 name:com.codefoxx.serviceexample.simpleintentservice.AnotherSimpleIntentService@9de157a
D/SimpleIntentService: sleep: 5 name:com.codefoxx.serviceexample.simpleintentservice.SimpleIntentService@ff71da5
D/AnotherSimpleIntentService: sleep: 5 name:com.codefoxx.serviceexample.simpleintentservice.AnotherSimpleIntentService@9de157a
D/SimpleIntentService: sleep: 6 name:com.codefoxx.serviceexample.simpleintentservice.SimpleIntentService@ff71da5
D/AnotherSimpleIntentService: sleep: 6 name:com.codefoxx.serviceexample.simpleintentservice.AnotherSimpleIntentService@9de157a
D/SimpleIntentService: sleep: 7 name:com.codefoxx.serviceexample.simpleintentservice.SimpleIntentService@ff71da5
D/AnotherSimpleIntentService: sleep: 7 name:com.codefoxx.serviceexample.simpleintentservice.AnotherSimpleIntentService@9de157a
D/SimpleIntentService: sleep: 8 name:com.codefoxx.serviceexample.simpleintentservice.SimpleIntentService@ff71da5
D/AnotherSimpleIntentService: sleep: 8 name:com.codefoxx.serviceexample.simpleintentservice.AnotherSimpleIntentService@9de157a
D/SimpleIntentService: sleep: 9 name:com.codefoxx.serviceexample.simpleintentservice.SimpleIntentService@ff71da5
D/SimpleIntentService: onDestroy:
D/AnotherSimpleIntentService: sleep: 9 name:com.codefoxx.serviceexample.simpleintentservice.AnotherSimpleIntentService@9de157a
D/AnotherSimpleIntentService: onDestroy:
可以看到不同的IntentService彼此不會互相影響,各自執行任務。
Orignal From: IntentService

