一、简介
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,完成生命周期绑定,处理完耗时操作无需自己处理。