【达内课程】音乐播放器4.0(图片显示、bitmap图片压缩)

专辑图片展示

ListView中异步批量加载图片业务
使用单线程轮循任务队列的机制完成该业务

修改接口多传一个参数 type,查询综合信息,修改 UrlFactory

public class UrlFactory {
    /**
     * url地址
     *
     * @param keyword
     * @return json
     */
    public static String getNewMusicListUrl(String keyword) {
        String url = "https://v2.alapi.cn/api/music/search?token=注册网站用户中心查看token&keyword=" + keyword+"&type=1018";
        return url;
    }
}

查看返回 json 数据
在这里插入图片描述
由于返回结构改变了,所以相应实体类

public class MusicDataModel {
    public MusicSongModel song;
}

public class MusicSongModel {
    public List<MusicItem> songs;
}

public class MusicItem {
    public String id;
    public String name;
    public String albumName;
    public String albumPic;
    public AlbumModel al;
}

public class AlbumModel {
    public String name;
    public String picUrl;
}

修改 JsonParser

public class JsonParser {
    /**
     * 通过输入流,通过XMLPULL解析方式 解析xml内容
     *
     * @param is
     * @return List<Music>
     */
    public static List<MusicItem> parseMusicList(InputStream is) throws IOException, JSONException {

        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        StringBuilder sb = new StringBuilder();
        String line = "";
        while ((line = reader.readLine()) != null) {
            sb.append(line);
        }
        String json = sb.toString();
        JSONObject obj = new JSONObject(json);
        JSONObject data = obj.getJSONObject("data");
        JSONObject song = data.getJSONObject("song");
        JSONArray songs = song.getJSONArray("songs");

        List<MusicItem> list = new ArrayList<>();
        for (int i = 0; i < songs.length(); i++) {
            JSONObject s = songs.getJSONObject(i);
            String id = s.getString("id");
            String name = s.getString("name");
            MusicItem musicItem = new MusicItem();
            musicItem.id = id;
            musicItem.name = name;
            musicItem.albumName = s.getJSONObject("al").getString("name");
            musicItem.albumPic = s.getJSONObject("al").getString("picUrl");
            list.add(musicItem);
        }
        return list;
    }
}

修改 MusicAdapter

public class MusicAdapter extends BaseAdapter {
    private Context context;
    private List<MusicItem> musics;
    private LayoutInflater inflater;
    private List<ImageLoaderTask> tasks = new ArrayList<ImageLoaderTask>();
    private Thread workThread;
    private boolean isLoop = true;
    private ListView listView;
    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case HANDLER_IMAGE_LOAD_SUCCESS:
                    //给相应的Imageview设置bitmap
                    ImageLoaderTask task = (ImageLoaderTask) msg.obj;
                    Bitmap bitmap = task.bitmap;
                    ImageView imageView = (ImageView) listView.findViewWithTag(task.path);
                    if (imageView != null) {
                        if (bitmap != null) {
                            imageView.setImageBitmap(bitmap);
                        } else {
                            imageView.setImageResource(R.mipmap.ic_launcher);
                        }
                    }
                    break;
            }
        }
    };

    public static final int HANDLER_IMAGE_LOAD_SUCCESS = 1;

    public MusicAdapter(Context context, List<MusicItem> musics, ListView listView) {
        super(context, musics);
        this.context = context;
        this.musics = musics;
        this.inflater = LayoutInflater.from(context);
        this.listView = listView;
        //启动工作线程,轮循任务集合
        workThread = new Thread() {
            @Override
            public void run() {
                while (isLoop) {
                    if (!tasks.isEmpty()) {//不是空集合
                        ImageLoaderTask task = tasks.remove(0);//remove的同时返回该数据
                        String url = task.path;
                        //发送http请求 下载图片
                        Bitmap bitmap = loadBitmap(url);
                        task.bitmap = bitmap;
                        //更新界面 发消息给Handler
                        Message message = new Message();
                        message.what = HANDLER_IMAGE_LOAD_SUCCESS;
                        message.obj = task;
                        handler.sendMessage(message);

                    } else {//空集合 等待
                        try {
                            //锁
                            synchronized (workThread) {
                                workThread.wait();
                            }
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        };
        workThread.start();
    }

    /**
     * 通过url地址 发送http请求 获取图片
     *
     * @param url
     * @return
     */
    private Bitmap loadBitmap(String url) {
        try {
            InputStream is = HttpUtils.getInputStream(url);
            Bitmap bitmap = BitmapFactory.decodeStream(is);
            return bitmap;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

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

    @Override
    public MusicItem getItem(int i) {
        return musics.get(i);
    }

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

    @Override
    public View getView(int i, View view, ViewGroup viewGroup) {
        ViewHolder holder = null;
        if (view == null) {
            view = inflater.inflate(R.layout.item_lv_music, null);
            holder = new ViewHolder();
            holder.imgPic = view.findViewById(R.id.img_Pic);
            holder.tvName = view.findViewById(R.id.tv_name);
            holder.tvAlbum = view.findViewById(R.id.tv_album);
            view.setTag(holder);
        }

        holder = (ViewHolder) view.getTag();
        //给控件赋值
        MusicItem music = getItem(i);
        holder.tvName.setText(music.name);
        holder.tvAlbum.setText(music.albumName);
        //图片在服务器,本来该起线程显示的,但是,这是adapter.getView()方法
        //每次图片显示时,都要启线程的话,手机会炸的...
        //给holder.imgPic设置图片
        //向任务集合中一个图片下载任务
        holder.imgPic.setTag(music.albumPic);
        ImageLoaderTask task = new ImageLoaderTask();
        task.path = music.albumPic;
        tasks.add(task);
        //唤醒工作线程,起来干活
        synchronized (workThread) {
            workThread.notify();
        }
        return view;
    }

    class ViewHolder {
        ImageView imgPic;
        TextView tvName;
        TextView tvAlbum;
    }

    class ImageLoaderTask {
        String path;//保存图片下载路径
        Bitmap bitmap;//下载成功后的图片
    }
}

NewMusicListFrament 修改如下

public void setAdapter(List<MusicItem> musics) {
        adapter = new MusicAdapter(getActivity(), musics, listView);
        listView.setAdapter(adapter);
    }

运行程序
在这里插入图片描述

图片压缩

Bitmap 图片压缩(位图对象)
常见图片格式:
JPG:最常用的压缩格式,压缩比率高,但是不支持透明色
PNG:支持透明色
GIF:支持动态图

提供一个工具类用来压缩 bitmap
BitmapUtils

public class BitmapUtils {

    /**
     * 压缩图片,获取相应尺寸的图片
     *
     * @param is     输入流
     * @param width  目标宽度
     * @param height 目标高度
     * @return
     */
    public static Bitmap loadBitmap(InputStream is, int width, int height) throws IOException {
        //把is解析,把数据读取到byte[]中
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        //把输入流中的数据读取到bos中
        byte[] buffer = new byte[1024 * 8];
        int length = 0;
        while ((length = is.read(buffer)) != -1) {
            bos.write(buffer, 0, length);
            bos.flush();
        }
        //该byte数组描述的是一个图片的完整信息
        byte[] bytes = bos.toByteArray();
        //获取图片原始尺寸
        BitmapFactory.Options options = new BitmapFactory.Options();
        //仅仅加载边界属性
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);
        //根据原始尺寸和width、height计算压缩比例
        int w = options.outWidth / width;
        int h = options.outHeight / height;
        int scale = w > h ? w : h;
        //执行压缩
        options.inJustDecodeBounds = false;
        options.inSampleSize = scale;//设置缩放比例
        Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);
        return bitmap;
    }
}

使用

Bitmap bitmap = BitmapUtils.loadBitmap(is,5,5);

应用到刚才的项目,修改 MusicAdapter 的 loadBitmap 方法

private Bitmap loadBitmap(String url) {
        try {
            InputStream is = HttpUtils.getInputStream(url);
            Bitmap bitmap = BitmapUtils.loadBitmap(is,100,100);
            //Bitmap bitmap = BitmapFactory.decodeStream(is);
            return bitmap;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值