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
0 意見:
張貼留言