HandlerThread 本质上是一个在子线程的handler(HandlerThread=Handler+Thread);
它的使用:
步骤1:创建HandlerThread实例对象 HandlerThread mHandlerThread = new HandlerThread("handlerThread");
步骤2:启动线程
mHandlerThread.start(); 步骤3:创建工作线程Handler&复写handleMessage () Handler workHandler = new Handler( handlerThread.getLooper() ) { @OverRide publicbooleanhandleMessage(Messagemsg){...//消息处理 return true; }
}); 步骤4:使用工作线程Handler向工作线程的消息队列发送 消 息 Message msg = Message.obtain(); msg.what = 2; //消息的标识 msg.obj = "B"; // 消息的存放 // b. 通过Handler发送消息到其绑定的消息队列 workHandler.sendMessage(msg); 步骤5:结束线程,即停止线程的消息循环 mHandlerThread.quit();
优势: 1.将loop运行在子线程中处理,减轻了主线程的压力,使主线程更流畅 2.串行执行,开启一个线程起到多个线程的作用 3.有自己的消息队列,不会干扰UI线程
劣势: 1.由于每一个任务队列逐步执行,一旦队列耗时过长,消息延时 2.对于IO等操作,线程等待,不能并发
IntentService 是 Service 的子类,默认为我们开启了一个工作线程,使用这个工作线程逐一处理所有启动请求,在任务执行完毕后会自动停止服务,使用简单,只要实现一个方法 onHandleIntent,该方法会接收每个启动请求的 Intent,能够执行后台工作和耗时操作。可以启动多次,而每一个耗时操作会以队列的方式在 IntentService的 回调方法中执行,并且,每一次只会执行一个工作线程,执行完第一个再执行第二个。并且等待所有消息都执行完后才终止服务。
IntentService适用于 APP 在不影响当前用户的操作的前提下,在后台默默的做一些操作。
IntentService源码:
1.通过HandlerThread单独开启一个名为IntentService的线程
2.创建一个名叫ServiceHandler的内部Handler
3.把内部Handler与HandlerThread所对应的子线程进行绑定
4.通过 onStartCommand()传递给服务 intent,依次插入到工作队列中,并逐个发送给onHandleIntent()
5.通过onHandleIntent()来依次处理所有Intent求对象所对应的任务
使用示例:
public class MyIntentService extends
IntentService {
public static final String TAG
="MyIntentService";
public MyIntentService()
{ super("MyIntentService"
);
}
@Override
protected void onHandleIntent(@Nullable Intent
intent) {
boolean isMainThread =
Thread.currentThread() ==
Looper.getMainLooper().getThread();
Log.i(TAG,"is main thread:"+isMainThread); //
这里会打印false,说明不是主线程
// 模拟耗时操作
download();
}
/**
* 模拟执行下载
*/
private void download(){ try {
Thread.sleep(5000);Log.i(TAG,"下载完成...");
}catch (Exception
e){ e.printStackTrace();
}
}
}
AsyncTask 的 实 现 原 理 :
1.AsyncTask是一个抽象类,主要由Handler+2个线程池构 成,SERIAL_EXECUTOR是任务队列线程池,用于调度任务,按顺序排列执行,THREAD_POOL_EXECUTOR是执行 线程池,真正执行具体的线程任务。Handler用于工作线程 和主线程的异步通信。 2.AsyncTask<Params,Progress,Result>,其中Params是doInBackground()方法的参数类型,Result是doInBackground()方法的返回值类型,Progress是onProgressUpdate()方法的参数类型。 3.当执行execute()方法的时候,其实就是调用SERIAL_EXECUTOR的execute()方法,就是把任务添加到队列的尾部,然后从头开始取出队列中的任务,调用THREAD_POOL_EXECUTOR的execute()方法依次执行,当 队列中没有任务时就停止。 4.AsyncTask只能执行一次execute(params)方法,否则会报错。但是SERIAL_EXECUTOR和THREAD_POOL_EXECUTOR线程池都是静态的,所以可以形成队列。
因为SERIAL_EXECUTOR和THREAD_POOL_EXECUTOR线程池都是静态的,所有的AsyncTask实例都共享这2个线程池, 因此形成了队列。
AsyncTask在创建对象的时候,会在构造函数中创建mWorker(workerRunnable)和mFuture(FutureTask)对象。mWorker实现了Callable接口的call()方法,在call()方法中,调用了doInBackground()方法,并在最后调用了postResult()方法,也就是通过Handler发送消息给主线程,在主线程中调用AsyncTask的finish()方法,决定是调 用onCancelled()还是onPostExecute(). mFuture实现了Runnable和Future接口,在创建对象时, 初始化成员变量mWorker,在run()方法中,调用 mWorker的call()方法。 当asyncTask执行execute()方法的时候,会先调用onPreExecute()方法,然后调用SERIAL_EXECUTOR的execute(mFuture),把任务加入到队列的尾部等待执行。执行的时候调用THREAD_POOL_EXECUTOR的execute(mFuture).
一般是用来将一个runnable绑定到主线程,在runOnUiThread源码里面会判断当前runnable是否是主线程,如果是直接run,如果不是,通过一个默认的空构造函数handler将runnable post 到looper里面,创建构造函数handler,会默认绑定一个主线程的looper对象
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。