Android-单线程轮循机制批量下载图片、图片压缩、内存泄漏、图片缓存、文件缓存

本文介绍了在Android中如何实现ListView异步批量加载图片,采用单线程轮循机制。同时,探讨了图片压缩的重要性,避免内存浪费和GC频繁触发导致的性能问题。讲解了Android内存泄漏的原因和解决方案,并分析了Java中的引用类型。此外,详细阐述了内存缓存和文件缓存的实现,包括使用SoftReference防止内存溢出以及图片的保存和读取策略。
摘要由CSDN通过智能技术生成

ListView异步批量加载图片

单线程轮循机制批量下载图片

例如:imageloader框架底层也是这么实现的!

思路:主线程向任务集合添加一个任务,工作线程从任务集合移除第一个任务,如果有任务一直移除,一直轮循,拿到图片之后解析成Bitmap,呈现的imageView当中。

这里写图片描述

package com.tarena.musicclient.adapter;

import java.io.IOException;
import java.lang.ref.SoftReference;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.util.EntityUtils;

import com.tarena.musicclient.activity.R;
import com.tarena.musicclient.entity.Music;
import com.tarena.musicclient.util.BitmapUtils;
import com.tarena.musicclient.util.GlobalConsts;
import com.tarena.musicclient.util.HttpUtils;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.Message;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

public class MusicAdapter extends BaseAdapter{
   
    private Context context;
    private List<Music> musics;
    private LayoutInflater inflater;
    //(2)声明任务集合  
    private List<ImageLoadTask> tasks=new ArrayList<ImageLoadTask>();
    private ListView listView;
    //声明用于轮循任务集合的工作线程
    private Thread workThread;
    //声明变量控制while循环
    private boolean isLoop=true;
    //声明缓存集合
    private HashMap<String, SoftReference<Bitmap>> cache 
        =new HashMap<String, SoftReference<Bitmap>>();

    //声明Handler  更新ImageView
    private Handler handler=new Handler(){
        public void handleMessage(android.os.Message msg) {
            switch (msg.what) {
            case HANDLER_LOAD_IMAGE_SUCCESS:
                //给ImageView设置Bitmap
                ImageLoadTask task=(ImageLoadTask)msg.obj;
                //通过tag寻找到相应的ImageView
                ImageView ivAlum=(ImageView)listView.findViewWithTag(task.position);
                if(ivAlum!=null){
                    if(task.bitmap!=null){
                        ivAlum.setImageBitmap(task.bitmap);
                    }else{
                        ivAlum.setImageResource(R.drawable.ic_launcher);
                    }
                }
                break;
            }
        }
    };

    public static final int HANDLER_LOAD_IMAGE_SUCCESS=0;


    public MusicAdapter(Context context, List<Music> musics, ListView listView) {
        this.context=context;
        this.musics=musics;
        this.listView=listView;
        inflater=LayoutInflater.from(context);
        //(5)MusicAdapter有几个,工作线程就有几个
        //对workThread进行初始化
        workThread=new Thread(){
            public void run() {
                //(6)不断轮循任务集合
                while(isLoop){
                    //如果任务集合不是空集  
                    if(!tasks.isEmpty()){
                        //获取任务对象并且发送请求 
                        ImageLoadTask task = tasks.remove(0);
                        //通过路径返回Bitmap对象
                        Bitmap bitmap=loadBitmap(task.path);
                        task.bitmap=bitmap;
                        //给相应的ImageView设置Bitmap   handler
                        Message msg=new Message();
                        msg.what=HANDLER_LOAD_IMAGE_SUCCESS;
                        msg.obj=task;
                        handler.sendMessage(msg);
                    }else{
                        //同步代码块:一但调用了某个对象的wait()/notify()方法后,外面一定套一个以这个对象为锁的同步代码块
                        synchronized (workThread) {
                            //如果任务集合是空集  wait等待
                            try {
                                workThread.wait();
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
            }
        };
        workThread.start();
    }

    /**
     * 通过path  获取Bitmap
     * @param path
     * @return
     */
    public Bitmap loadBitmap(String path){
        Bitmap bitmap=null;
        String uri=GlobalConsts.BASEURL+path;
        try {
            //实体转成字节数组,字节数组转成图片
            HttpEntity entity=HttpUtils.send(HttpUtils.METHOD_GET, uri, null);
            byte[] bytes=EntityUtils.toByteArray(entity);
            bitmap=BitmapUtils.loadBitmap(bytes, 50, 50);
            //向缓存集合中存储缓存图片
            cache.put(path, new SoftReference<Bitmap>(bitmap));

        } catch (IOException e) {
            e.printStackTrace();
        }
        return bitmap;
    }

    @Override
    public int getCount() {
        return musics.size();
    }

    public Object getItem(int position) {
        return musics.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    public View getView(int
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值