【達內課程】音樂播放器4.0(優化)
阿新 • • 發佈:2018-11-08
最後可以對圖片進行壓縮,可以檢視
https://blog.csdn.net/u010356768/article/details/83016046
增加BitmapUtils檔案後
MusicAdapter中修改以下方法
private Bitmap loadBitmap(String url){ try { InputStream is = HttpUtils.getInputStream(url); //執行壓縮演算法,獲取合適尺寸的圖片 Bitmap bitmap = BitmapUtils.loadBitmap(is,5,5); //Bitmap bitmap = BitmapFactory.decodeStream(is); return bitmap; } catch (IOException e) { e.printStackTrace(); } return null; }
如何使用軟引用實現記憶體快取
修改MusicAdapter
/** * 音樂列表介面卡 */ public class MusicAdapter extends BaseAdapter { ...... private ListView listView; private HashMap<String,SoftReference<Bitmap>> cache = new HashMap<>(); ...... /** * 通過url地址 傳送http請求 獲取圖片 * @param url * @return */ private Bitmap loadBitmap(String url){ try { InputStream is = HttpUtils.getInputStream(url); //執行壓縮演算法,獲取合適尺寸的圖片 Bitmap bitmap = BitmapUtils.loadBitmap(is,50,50); //Bitmap bitmap = BitmapFactory.decodeStream(is); //把bitmap放入記憶體快取 cache.put(url,new SoftReference<Bitmap>(bitmap)); return bitmap; } catch (IOException e) { e.printStackTrace(); } return null; } ...... @Override public View getView(int i, View view, ViewGroup viewGroup) { ViewHolder holder = null; ...... //給holder.imgPic設定圖片 //先去記憶體快取中看有沒有 SoftReference<Bitmap> ref = cache.get(music.getPic_small()); if(ref!=null){//以前存過 Bitmap bitmap = ref.get(); if(bitmap!=null){//以前存的還沒有被清掉 holder.imgPic.setImageBitmap(bitmap); return view; } } //向任務集合中一個圖片下載任務 holder.imgPic.setTag(music.getPic_small()); ...... return view; } ...... }
檔案快取
BitmapUtils增加如下方法
/** * 用jpeg格式儲存bitmap * * @param bitmap * @param file */ public static void save(Bitmap bitmap, File file) throws IOException { if (!file.getParentFile().exists()) {//父目錄不存在 file.getParentFile().mkdirs(); } FileOutputStream fos = new FileOutputStream(file); bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos); } /** * 從檔案中載入一個Bitmap * * @param file * @return */ public static Bitmap bitmap(File file) { if (!file.exists()) { return null; } Bitmap b = BitmapFactory.decodeFile(file.getAbsolutePath()); return b; }
MusicAdapter修改如下
/**
* 音樂列表介面卡
*/
public class MusicAdapter extends BaseAdapter {
......
private ListView listView;
private HashMap<String,SoftReference<Bitmap>> cache = new HashMap<>();
......
/**
* 通過url地址 傳送http請求 獲取圖片
* @param url
* @return
*/
private Bitmap loadBitmap(String url){
try {
InputStream is = HttpUtils.getInputStream(url);
//執行壓縮演算法,獲取合適尺寸的圖片
Bitmap bitmap = BitmapUtils.loadBitmap(is,50,50);
//Bitmap bitmap = BitmapFactory.decodeStream(is);
//把bitmap放入記憶體快取
cache.put(url,new SoftReference<Bitmap>(bitmap));
//把bitmap存入檔案中
//data/data/包名/cache資料夾 內部儲存的快取目錄
String fileName = url.substring(url.lastIndexOf("/")+1);
Log.d("IMAGES",fileName);
File file = new File(context.getCacheDir(),"images/"+fileName);
BitmapUtils.save(bitmap,file);
return bitmap;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
......
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
ViewHolder holder = null;
......
//圖片在伺服器,本來該起執行緒顯示的,但是,這是adapter.getView()方法
//每次圖片顯示時,都要啟執行緒的話,手機會炸的...
//給holder.imgPic設定圖片
//先去記憶體快取中看有沒有
SoftReference<Bitmap> ref = cache.get(music.getPic_small());
if(ref!=null){//以前存過
Bitmap bitmap = ref.get();
if(bitmap!=null){//以前存的還沒有被清掉
holder.imgPic.setImageBitmap(bitmap);
return view;
}
}
//去檔案快取中讀取
String url = music.getPic_small();
String fileName = url.substring(url.lastIndexOf("/")+1);
File file = new File(context.getCacheDir(),"images/"+fileName);
Bitmap bitmap = BitmapUtils.bitmap(file);
if(bitmap!=null){
//一旦從檔案中讀取出來,先存入記憶體快取
//記憶體是最快的
cache.put(url,new SoftReference<Bitmap>(bitmap));
holder.imgPic.setImageBitmap(bitmap);
return view;
}
//向任務集合中一個圖片下載任務
......
return view;
}
......
}
檢視data/data/包名/cache可以看到下載的圖片
封裝
新增ImageLoader
import android.content.Context;
import android.graphics.Bitmap;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.ImageView;
import android.widget.ListView;
import com.example.xx.v4.R;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
/**
* 非同步批量載入圖片的工具類
*/
public class ImageLoader {
private HashMap<String,SoftReference<Bitmap>> cache = new HashMap<>();
private Context context;
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 ImageLoader(Context context,ListView listView) {
this.context = context;
this.listView = listView;
//啟動工作執行緒,輪循任務集合
//匿名內部類持有外部類物件引用
//在匿名內部類中可以使用MusicAdapter.this
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();
}
public void stopThread(){
//isLoop為false,迴圈停止
isLoop = false;
//當我們按返回鍵時,執行緒在wait(),應先喚醒
synchronized (workThread) {
workThread.notify();
}
}
public void displayImage(String url, ImageView imageView){
//先去記憶體快取中看有沒有
SoftReference<Bitmap> ref = cache.get(url);
if(ref!=null){//以前存過
Bitmap bitmap = ref.get();
if(bitmap!=null){//以前存的還沒有被清掉
imageView.setImageBitmap(bitmap);
return;
}
}
//去檔案快取中讀取
String fileName = url.substring(url.lastIndexOf("/")+1);
File file = new File(context.getCacheDir(),"images/"+fileName);
Bitmap bitmap = BitmapUtils.bitmap(file);
if(bitmap!=null){
//一旦從檔案中讀取出來,先存入記憶體快取
//記憶體是最快的
cache.put(url,new SoftReference<Bitmap>(bitmap));
imageView.setImageBitmap(bitmap);
return;
}
//向任務集合中一個圖片下載任務
imageView.setTag(url);
ImageLoaderTask task = new ImageLoaderTask();
task.path = url;
tasks.add(task);
//喚醒工作執行緒,起來幹活
synchronized (workThread) {
workThread.notify();
}
}
class ImageLoaderTask{
String path;//儲存圖片下載路徑
Bitmap bitmap;//下載成功後的圖片
}
/**
* 通過url地址 傳送http請求 獲取圖片
* @param url
* @return
*/
private Bitmap loadBitmap(String url){
try {
InputStream is = HttpUtils.getInputStream(url);
//執行壓縮演算法,獲取合適尺寸的圖片
Bitmap bitmap = BitmapUtils.loadBitmap(is,50,50);
//Bitmap bitmap = BitmapFactory.decodeStream(is);
//把bitmap放入記憶體快取
cache.put(url,new SoftReference<Bitmap>(bitmap));
//把bitmap存入檔案中
//data/data/包名/cache資料夾 內部儲存的快取目錄
String fileName = url.substring(url.lastIndexOf("/")+1);
Log.d("IMAGES",fileName);
File file = new File(context.getCacheDir(),"images/"+fileName);
BitmapUtils.save(bitmap,file);
return bitmap;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
MusicAdapter修改為
import android.content.Context;
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;
import com.example.xx.v4.R;
import com.example.xx.v4.entity.Music;
import com.example.xx.v4.util.ImageLoader;
import java.util.List;
/**
* 音樂列表介面卡
*/
public class MusicAdapter extends BaseAdapter {
private Context context;
private List<Music> musics;
private LayoutInflater inflater;
private ImageLoader imageLoader;
public MusicAdapter(Context context, List<Music> musics, ListView listView) {
super();
this.context = context;
this.musics = musics;
this.inflater = LayoutInflater.from(context);
this.imageLoader = new ImageLoader(context,listView);
}
@Override
public int getCount() {
return musics.size();
}
@Override
public Music 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.tvSinger = view.findViewById(R.id.tv_singer);
view.setTag(holder);
}
holder = (ViewHolder) view.getTag();
//給控制元件賦值
Music music = getItem(i);
holder.tvName.setText(music.getTitle());
holder.tvSinger.setText(music.getAuthor());
//圖片在伺服器,本來該起執行緒顯示的,但是,這是adapter.getView()方法
//每次圖片顯示時,都要啟執行緒的話,手機會炸的...
//給holder.imgPic設定圖片
imageLoader.displayImage(music.getPic_small(),holder.imgPic);
return view;
}
public void stopThread() {
imageLoader.stopThread();
}
class ViewHolder{
ImageView imgPic;
TextView tvName;
TextView tvSinger;
}
}