一、簡介
IntentService is a base class for {@link Service}s that handle asynchronous
* requests (expressed as {@link Intent}s) on demand. Clients send requests
* through {@link android.content.Context#startService(Intent)} calls; the
* service is started as needed, handles each Intent in turn using a worker
* thread, and stops itself when it runs out of work.
// IntentService用於處理異步請求,使用工作線程(子線程)處理每個intent,工作完後停止自己
* <p>This "work queue processor" pattern is commonly used to offload tasks
* from an application's main thread. The IntentService class exists to
* simplify this pattern and take care of the mechanics. To use it, extend
* IntentService and implement {@link #onHandleIntent(Intent)}. IntentService
* will receive the Intents, launch a worker thread, and stop the service as
* appropriate.
// 使用時需要繼承IntentService 實現onHandleIntent(Intent)方法,IntentService會接收到intents啓動一個工作線程,並且會適當的停止服務
* <p>All requests are handled on a single worker thread -- they may take as
* long as necessary (and will not block the application's main loop), but
* only one request will be processed at a time.
// 所有的請求會在一個單獨的工作線程處理,在不阻塞應用主循環的前提下會盡可能長存活,但是每次只處理一個請求
二、基本使用
1、創建類繼承IntentService,並重寫onHandleIntent()方法,重寫無參構造方法
public class MyIntentService extends IntentService {
private int progress = 0;
public MyIntentService() {
super("MyIntentService");
}
@Override
protected void onHandleIntent(@Nullable Intent intent) {
try {
// 模擬耗時操作
Thread.sleep(1000);
while (true) {
progress++;
if (progress > 100) {
break;
}
sendBroadCast();
Thread.sleep(100);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void sendBroadCast() {
Intent mIntent = new Intent();
mIntent.setAction("updateProgress");
mIntent.putExtra("updateProgress", progress);
getApplicationContext().sendBroadcast(mIntent);
}
}
2、Activity中調用並更新UI
public class IntentServiceActivity extends Activity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_intent_service);
initBroadCastReceiver();
initView();
}
private void initBroadCastReceiver() {
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("updateProgress");
registerReceiver(broadcastReceiver, intentFilter);
}
private void initView() {
Button btnStartService = findViewById(R.id.btn_start);
btnStartService.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setClass(IntentServiceActivity.this, MyIntentService.class);
startService(intent);
}
});
}
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction() == "updateProgress") {
int progress = intent.getIntExtra("updateProgress", 0);
ProgressBar progressBar = findViewById(R.id.progressBar);
progressBar.setProgress(progress);
if (progress == 100) {
Toast.makeText(IntentServiceActivity.this, "downLoadSuccess", Toast.LENGTH_SHORT).show();
}
}
}
};
}
3、layout文件
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/btn_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="start_service"/>
<ProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_marginTop="20dp"
/>
</android.support.v7.widget.LinearLayoutCompat>
4、效果圖
三、源碼分析
// 抽象類繼承Service,爲Service的子類
public abstract class IntentService extends Service
構造方法
// 被子類構造調用
/**
* Creates an IntentService. Invoked by your subclass's constructor.
*
* @param name Used to name the worker thread, important only for debugging.
*/
public IntentService(String name) {
super();
mName = name;
}
onCreate()
@Override
public void onCreate() {
// TODO: It would be nice to have an option to hold a partial wakelock
// during processing, and to have a static startService(Context, Intent)
// method that would launch the service & hand off a wakelock.
super.onCreate();
// 創建一個線程
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
// 獲取線程的Looper
mServiceLooper = thread.getLooper();
// 使用當前線程looper創建線程
mServiceHandler = new ServiceHandler(mServiceLooper);
}
ServiceHandler
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
// 處理消息
onHandleIntent((Intent)msg.obj);
// 處理完後調用stopSelf,停止當前服務
stopSelf(msg.arg1);
}
}
onStartCommand()
@Override
public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
// 調用onStart方法
onStart(intent, startId);
return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}
onStart()
@Override
public void onStart(@Nullable Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
// 通過mServiceHandler發送消息
mServiceHandler.sendMessage(msg);
}
onDestroy()
@Override
public void onDestroy() {
// 生命週期結束直接將looper關閉,所以在該service使用完後會自動關閉
mServiceLooper.quit();
}
總結:
intentService通過創建子線程進行耗時操作,結合handler進行線程切換操作,所以可以進行耗時操作,在onDestroy()方法中,將當前工作線程的looper關閉,同時在handleMessage中通過stopSelf(msg.arg1);關閉service,完成生命週期綁定,處理完耗時操作無需自己處理。