我们平常写程序时经常会涉及到下载或者播放音乐等耗时操作,你可能会使用Service+Thread的方式解决,但是这样比较麻烦,如果你要串行执行多个耗时操作还要使用线程池,其实Google早就帮我们封装好了一个框架——IntentService
一、简单使用
Client端
public class ClientActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
//客户端同时发送两个任务到IntentService服务端执行
public void send(View view) {
Intent intent = new Intent(this, DownLoadService.class);
intent.putExtra("value", "task1");
startService(intent);
Intent intent1 = new Intent(this, DownLoadService.class);
intent1.putExtra("key", 2);
intent1.putExtra("value", "task2");
startService(intent1);
}
}
Service端
public class DownLoadService extends IntentService {
public static final String TAG = "DownLoadService";
public DownLoadService() {
super("DownLoadService");
}
@Override
protected void onHandleIntent(Intent intent) {
String value = intent.getStringExtra("value");
switch (key) {
case 1:
//耗时任务1
try {
Thread.sleep(3 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
break;
case 2:
//耗时任务2
try {
Thread.sleep(3 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
break;
default:
break;
}
}
}
因为它本身还是一个Service所以还需要在AndroidManfiest中进行注册,
需要注意的点:
- 只要耗时操作一执行完它就会停止
- 只能通过startService开启
二、源码分析
1.构造方法
public IntentService(String name) {
super();
mName = name;
}
传入的name是内部线程的名字
2.onCreate()
public void onCreate() {
super.onCreate();
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
该方法首先创建了一个HandlerThread,并调用了它的start方法,然后实例化了一个Handler并与HandlerThread的Looper绑定
3.onStartCommand()
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
onStart(intent, startId);
return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}
在里面调用了onStart方法,在IntentService中你无需重写此方法
@Override
public void onStart(Intent intent, int startId) {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent;
mServiceHandler.sendMessage(msg);
}
在onStart里创建了一个Message,并将intent赋值给它的obj属性,使用Handler发送消息,所以说必须使用startService启动IntentService
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
onHandleIntent((Intent)msg.obj);
stopSelf(msg.arg1);
}
}
在Handler的handleMessage中处理消息,将消息传给onHandleIntent处理,onHandleIntent也是抽象方法,你必须重写此方法来对不同的intent进行不同的处理,处理完后调用stopSelf结束自己
4.onDestory()
@Override
public void onDestroy() {
mServiceLooper.quit();
}
最后调用quit停止looper
三、总结
首先在IntentService的构造方法里面你会看到创建了 一个HandlerThread线程出来,并且调用了它的start方法启动了该线程,之前在HandlerThread总结中已经讲过会在该线程的run方法里面创建Looper对象并且调用loop将Looper运转起来,接着会通过创建的Looper对象创建一个ServiceHandler出来,其实就是Handler对象而已,该对象里面有handleMessage方法,在我们通过startService方法启动IntentService的时候 会回调onStartCommand方法,该方法会执行IntentService的onStart方法,而正是在onStart方法里面会将我们 startService传入的intent对象封装成Message对象通过在构造函数中创建的ServiceHandler类型handler对象的sendMessage方法发送出去,那么紧接着就会回调ServiceHandler的handleMessage方法了,handleMessage方法实际上执行的是onHandleIntent方法,也就是我们在实现IntentService抽象类的时候需要实现的方法,具体实现对Intent的操作,操作结束之后handleMessage方法会执行stopSelf方法结束当前IntentService;