安卓图片加载框架的学习

来源:互联网 发布:南方大数据110指数基金 编辑:程序博客网 时间:2024/05/01 08:58

最近在学习张鸿洋的写的图片加载框架: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();


0 0