最近在学习张鸿洋的写的图片加载框架:http://blog.csdn.net/lmj623565791/article/details/41874561,受益颇多,自己再按照理解,打了一遍,在图片加载那块,原生博客已写得很清楚,这里就不说了,这里主要写自己在读代码时遇到的问题,分别是Loop线程的Handler和UIHandler两个之间的区分;线程池和信号量的使用。
安卓系统本身有一个管理UI线程的Loop,如果我们没有把Handler写在Thread线程里的话,那么它发送的消息都会被这个Loop管理,就好像这个UIHandler。但如果把Handler单独写在Thread里的话,就必须要有Loop.prepare()和Loop.loop()语句,否则会报错。
代码如下:
//创建轮询线程
mPoolThread = new Thread() {
@Override
public void run() {
Looper.prepare();
//处理轮询消息
mPoolThreadHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
Log.i("Luo", "excute Task " + count);
// 线程池去取出一个任务执行
mThreadPool.execute(getThreadTask());
try {
//信号量-1
mSemaphoreThreadPool.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Looper.loop();
}
};
mPoolThread.start();
只要是mPoolThreadHandler发送的消息就不会被系统的UI线程接收,因为是两个不同的消息队列。
接下来简单说说线程池和信号量的使用,其实自己前段时间有去仔细地了解过线程池的使用,但没有了解过信号量的使用,这个知识点终于把以前学到的操作系统知识给用到了,开心下。
// 创建线程池
mThreadPool = Executors.newFixedThreadPool(threadCount);
// 创建任务队列,这个任务队列是为了暂时储存线程,等线程池里的某个线程执行完,信息量就会通知Loop继续执行取出的线程,这时是由Loop线程里的Handler完成
mTaskQueue = new LinkedList<Runnable>();
//创建信息量,这个信号量是为了让Loop的执行不要太快,一次只要threadCount来;信号量一开始为threadCount,执行一次,减一,<=0时停止执行
mSemaphoreThreadPool = new Semaphore(threadCount);
信号量在执行完线程时,必须释放资源,否则其它线程无法执行:
mSemaphoreThreadPool.release();