前言:
-
由于Android的特性,如果在主线程中执行耗时操作会导致程序无法及时响应,因此耗时的操作必须放在子线程中去执行。(如网络请求、访问大量数据)。
-
尽管AsyncTask、HanderThread,IntentService的表现形式都有别于传统的线程,但是它们的本质都是传统的线程。
-
AsyncTask封装了线程池和Handler,它主要是为了开发者在子线程中更新UI。
-
HandlerThread是一种具有消息循环的线程,它的内部可以使用Handler。
-
IntentService是一个服务,系统对其进行了封装使其可以更方便地执行后台服务,IntentService内部采用了HandlerTHread来执行任务,当任务执行完了之后会自动退出。
1、 AsyncTask
使用方法:创建类继承自AsyncTask,重写一系列方法
(方法作用看代码注释)
public class MyAsyncTask extends AsyncTask<String ,Long,Long> {
Context context;
public MyAsyncTask(Context context) {
this.context = context;
}
//任务开始前调用
@Override
protected void onPreExecute() {
super.onPreExecute();
Toast.makeText(context,"开始执行AsyncTask,咋哇撸多!",Toast.LENGTH_SHORT).show();
}
//后台执行任务时调用
@Override
protected Long doInBackground(String... strings) {
for(int i=0;i<3;i++){
Log.d("time",i+"秒过去了");
try {
//一些耗时操作。。。
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return null;
}
//后台任务执行进度发生变化时调用
@Override
protected void onProgressUpdate(Long... values) {
super.onProgressUpdate(values);
}
//任务结束时调用
@Override
protected void onPostExecute(Long aLong) {
super.onPostExecute(aLong);
Toast.makeText(context,"AsyncTask执行完毕!",Toast.LENGTH_SHORT).show();
}
}
asyncTaskBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new MyAsyncTask(MainActivity.this).execute("");
}
});
}
注意事项:
- AsyncTask的对象必须在主线程中调用。
- excute方法必须在UI线程调用。
- 不要再程序中直接调用重写的四个方法。
- 一个AsyncTask对象只能执行一次,即只能执行一次execute方法,否则会报运行异常。
- Android1.6之前,AsyncTask时串行执行任务的,Android1.6的时候采用线程处理并行任务,Android3.0开始为了避免AsyncTask带来的并发错误,AsyncTask又采用一个线程来串行执行任务。尽管如此,3.0以后的版本,仍然可以使用AsyncTask.的executeOnExecutor方法来并行地执行任务。
2、HandlerThread
HandleThread继承了Thread,它是一种可以使用Handler的Thread,它的实现就是在run方法中通过Loop.prepare()来创建消息队列,并通过Looper.loop()来开启消息循环,这样在实际的使用中就允许在HandlerThread中创建Hander。
注意事项:
- 它在Android中的一个使用场景是IntentService。
- HandlerThread的run方法是一个无限循环,因此当明确不需要再使用HanderThread时要使用quit或者quitSafely方法来终止线程的执行。
使用方法:
//1、创建handlerThread,并启动线程
final HandlerThread handlerThread = new HandlerThread("MyHandlerThread");
handlerThread.start();
//2、创建工作线程
final Handler workHandler = new Handler(handlerThread.getLooper()){
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
if( msg.what = 0){
//do something...
}
}
//使用handler发送消息
Message msg = Message.obtain();
msg.what=0;
workHandler.sendMessage(msg);
//结束handlerThread
handlerThread.quit();
3、IntentService
简介:
- IntentService是一种特殊的Service,它继承了Service并且它是一个抽象类,因此必须创建它的子类才能使用它。
- IntentService可用于执行后台耗时任务(如下载),当任务执行完会自动停止。
- 由于IntentService是Service的原因,因此可以执行高优先级的后台任务,因为优先级高,所以不容易被系统杀死。
首先看IntentService的onCreate方法的源码,执行该方法时,会新建一个HandlerThread,然后调用它的Looper来构造一个Handler对象mServiceHandler(所以说IntentService是HandlerThread的一个使用场景)
public void onCreate() {
super.onCreate();
HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
thread.start();
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);
}
使用方法:
(记得在manifest中声明服务)
public class MyIntentService extends IntentService {
public MyIntentService(String name) {
super(name);
}
@Override
protected void onHandleIntent(@Nullable Intent intent) {
String action = intent.getStringExtra("task_action");
Log.d("MyIntentService","receive action:"+action);
SystemClock.sleep(2000);
}
}
intentServiceBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent service = new Intent(MainActivity.this,MyIntentService.class);
service.putExtra("task_action","----------Task1");
startService(service);
service.putExtra("task_action","----------Task2");
startService(service);
service.putExtra("task_action","----------Task3");
startService(service);
}
});
运行结果: