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 position, View convertView, ViewGroup parent) {
ViewHolder holder=null;
if(convertView==null){
convertView=inflater.inflate(R.layout.item_lv_music, null);
holder=new ViewHolder();
holder.ivAlbum=(ImageView)convertView.findViewById(R.id.imageView1);
holder.tvName=(TextView)convertView.findViewById(R.id.tvName);
holder.tvDuration=(TextView)convertView.findViewById(R.id.tvDuration);
holder.tvSinger=(TextView)convertView.findViewById(R.id.tvSinger);
holder.tvAuthor=(TextView)convertView.findViewById(R.id.tvAuthor);
convertView.setTag(holder);
}
holder=(ViewHolder)convertView.getTag();
//給控件賦值
Music music=musics.get(position);
holder.tvName.setText(music.getName());
holder.tvSinger.setText(music.getSinger());
holder.tvAuthor.setText(music.getAuthor());
holder.tvDuration.setText(music.getDurationtime());
//給當前item中的ImageView設置一個Tag
//用於圖片下載完成後根據該tag
//找到相應的ImageView
holder.ivAlbum.setTag(position);
//查詢緩存中是否有圖片 如果有 則直接獲取
SoftReference<Bitmap> ref=cache.get(music.getAlbumpic());
if(ref!=null && ref.get()!=null){
Bitmap bitmap=ref.get();
holder.ivAlbum.setImageBitmap(bitmap);
System.out.println("從緩存中讀取圖片..");
return convertView;
}
//(3)下載一張圖片
//向任務隊列中添加一個圖片任務
ImageLoadTask task=new ImageLoadTask();
//albumPic: images/xxxxx.jpg
task.path=music.getAlbumpic();
task.position=position;
tasks.add(task);
//(4)喚醒工作線程 起來幹活
notifyWorkThread();
return convertView;
}
/**
* 喚醒工作線程
*/
public void notifyWorkThread(){
//注意:一但調用wait活notify方法的時候,就要在這個同步代碼塊對象上加鎖
synchronized (workThread) {
workThread.notify();
}
}
//(1)創建圖片下載任務類型的類
class ImageLoadTask{
String path;//圖片路徑
Bitmap bitmap;//圖片對象
int position;
}
class ViewHolder{
ImageView ivAlbum;
TextView tvName;
TextView tvDuration;
TextView tvSinger;
TextView tvAuthor;
}
public void stopWorkThread() {
isLoop=false;
notifyWorkThread();
}
}
圖片壓縮
圖片壓縮的意義:(像一些小圖標,不需要很高清)
例如我們寫的上面的程序圖片都是從服務器端下載下來的,一個圖片大小是5k,但是這個5k的圖片加載到內存裏就不止是5k了,一個Bitmap肯定比5k要多(5k的十倍)50k,10張就500k(半兆),這樣圖片多了的話就非常浪費內存,佔用內存!當佔用內存十分大的時候,android 手機就會出現GC(垃圾回收機制),自動銷燬堆內存中的垃圾。如果java管理的內存越來越滿,快溢出了,GC執行頻率會上升,導致效果:在GC執行垃圾回收的時候,所有的線程暫停,主線程也不準繪製UI!如果GC執行頻率非常頻繁,肯定會出現吊幀,卡頓的現象!
Bitmap圖片(位圖對象):
BitmapFactory 圖片工廠:
Options封裝了創建Bitmap對象時使用的參數
package com.tarena.musicclient.adapter;
import java.io.IOException;
import java.util.ArrayList;
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;
//聲明任務集合
private List<ImageLoadTask> tasks=new ArrayList<ImageLoadTask>();
private ListView listView;
//聲明用於輪循任務集合的工作線程
private Thread workThread;
//聲明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);
//對workThread進行初始化
workThread=new Thread(){
public void run() {
//不斷輪循任務集合
while(true){
//如果任務集合不是空集
if(!tasks.isEmpty()){
//獲取任務對象並且發送請求
ImageLoadTask task = tasks.remove(0);
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{
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);
} 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 position, View convertView, ViewGroup parent) {
ViewHolder holder=null;
if(convertView==null){
convertView=inflater.inflate(R.layout.item_lv_music, null);
holder=new ViewHolder();
holder.ivAlbum=(ImageView)convertView.findViewById(R.id.imageView1);
holder.tvName=(TextView)convertView.findViewById(R.id.tvName);
holder.tvDuration=(TextView)convertView.findViewById(R.id.tvDuration);
holder.tvSinger=(TextView)convertView.findViewById(R.id.tvSinger);
holder.tvAuthor=(TextView)convertView.findViewById(R.id.tvAuthor);
convertView.setTag(holder);
}
holder=(ViewHolder)convertView.getTag();
//給控件賦值
Music music=musics.get(position);
holder.tvName.setText(music.getName());
holder.tvSinger.setText(music.getSinger());
holder.tvAuthor.setText(music.getAuthor());
holder.tvDuration.setText(music.getDurationtime());
//給當前item中的ImageView設置一個Tag
//用於圖片下載完成後根據該tag
//找到相應的ImageView
holder.ivAlbum.setTag(position);
//下載一張圖片
//向任務隊列中添加一個圖片任務
ImageLoadTask task=new ImageLoadTask();
//albumPic: images/xxxxx.jpg
task.path=music.getAlbumpic();
task.position=position;
tasks.add(task);
//喚醒工作線程 起來幹活
notifyWorkThread();
return convertView;
}
/**
* 喚醒工作線程,起來運行跳出循環
*/
public void notifyWorkThread(){
synchronized (workThread) {
workThread.notify();
}
}
class ImageLoadTask{
String path;
Bitmap bitmap;
int position;
}
class ViewHolder{
ImageView ivAlbum;
TextView tvName;
TextView tvDuration;
TextView tvSinger;
TextView tvAuthor;
}
}
圖片壓縮工具類
package com.tarena.musicclient.util;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
public class BitmapUtils {
/**
* 通過字節數組解析出Bitmap對象
* 需要按照一定的寬高的規格進行壓縮
* @param bytes 數據源
* @param width 圖片的目標寬度
* @param height 圖片的目標高度
* @return
*/
public static Bitmap loadBitmap(byte[] bytes, int width, int height) {
Options opt=new Options();
//設置是否僅僅加載邊界屬性
opt.inJustDecodeBounds=true;
BitmapFactory.decodeByteArray(bytes, 0, bytes.length, opt);
//獲取圖片的原始的高度與寬度
int w=opt.outWidth/width;
int h=opt.outHeight/height;
int scale=w>h ? w : h;
//設置壓縮比例
opt.inSampleSize=scale;
//再次進行解析Bitmap
opt.inJustDecodeBounds=false;
return BitmapFactory.decodeByteArray(bytes, 0, bytes.length, opt);
}
}
Android 內存泄漏
Android內存當中有垃圾對象,這些垃圾對象被佔用了之後還不能被GC(垃圾回收機制回收)內存也不能重複利用,導致內存泄漏。
GC垃圾回收機制:
項目中內存泄漏中的地方:
解決方法:
在Activity生命週期方法中銷燬的時候關閉當前線程,詳情看上方代碼
內存泄漏最常見的情況:
Thread
new Thread (){}.start()必須給出run方法執行完畢的條件,在應用程序退出的時候銷燬工作線程。
查看本程序中運行的線程
Java中的引用
強引用: StrongReference
e=new Emp();
就算出OOM,也不會銷燬強引用
軟引用: SoftReference
弱java管理的內存接近閾值,將會銷燬一些軟引用。釋放內存
弱引用: WeakReference
就算java管理的內存沒有接近閾值,就會銷燬一些弱引用。
虛引用: …………
由GC管理的。
軟引用的使用:
SoftReference s=new SoftReference(bitmap);
Bitmap bitmap=s.get();
Android圖片的內存緩存
第一次把圖片下載到手機後,存入內存中,再次需要下載圖片時,先去內存中查詢,如果已經下載過,那麼直接獲取,如果沒有獲取過,再去下載。
存:
注意:
一直存會容易c內存溢出OOM
HashMap < String,Bitmap > cache ;
cache.put(“images/jsjs.jpg”,bitmap);
cache.put(“images/jsjs.jpg”,bitmap);
cache.put(“images/jsjs.jpg”,bitmap);
cache.put(“images/jsjs.jpg”,bitmap);
cache.put(“images/jsjs.jpg”,bitmap);
WeakHashMap:
弱引用,當java的內存達到閾值的時候,會隨機刪除鍵值對。
取:
Bitmap bitmap=cache.get(“images/jsjs.jpg”);
改進後:
HashMap < String,SoftReference> map;
map.put(path,new SoftReference(bitmap));
map.get(path).get();
代碼參考上方例子
圖片的文件緩存
(1)下載圖片後,把圖片數據保存到應用的緩存目錄中。
public void save(File targetFile,Bitmap bitmap)//工具類存的方法
Bitmap bitmap;
FileOutputStream fos;//寫出到文件
file.write();
//緩存目錄都存到cach文件中
bimap.compress();//壓縮方法
(2)再次獲取圖片時,先去內存緩存中去查詢,如果沒有則去緩存目錄中查詢。有則直接讀取。沒有的話再次發送請求。
public Bitmap loadBitmap(path)//工具類方法:通過路徑加載bitmap,也可以出入壓縮的比例
String path;
BitmapFactory.decodeFile(path,Options);
文件緩存工具類方法:
package com.tarena.musicclient.util;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
public class BitmapUtils {
/**
* 通過一個文件路徑 查找到Bitmap
* @param path
* @return
* @throws IOException
*/
public static Bitmap loadBitmap(String path)throws IOException{
File file=new File(path);
if(file.exists()){
return BitmapFactory.decodeFile(path);
}
return null;
}
/***
* 保存圖片
* @param targetFile 目標文件
* @param bitmap 位圖對象
* @throws IOException
*/
public static void save(File targetFile, Bitmap bitmap)throws IOException{
if(!targetFile.getParentFile().exists()){
//父目錄不存在 則創建
targetFile.getParentFile().mkdirs();
}
if(!targetFile.exists()){
targetFile.createNewFile();
}
//寫入
FileOutputStream fos=new FileOutputStream(targetFile);
bitmap.compress(CompressFormat.JPEG, 100, fos);
}
/**
* 通過字節數組解析出Bitmap對象
* 需要按照一定的寬高的規格進行壓縮
* @param bytes 數據源
* @param width 圖片的目標寬度
* @param height 圖片的目標高度
* @return
*/
public static Bitmap loadBitmap(byte[] bytes, int width, int height) {
Options opt=new Options();
//設置是否僅僅加載邊界屬性
opt.inJustDecodeBounds=true;
BitmapFactory.decodeByteArray(bytes, 0, bytes.length, opt);
//獲取圖片的原始的高度與寬度
int w=opt.outWidth/width;
int h=opt.outHeight/height;
int scale=w>h ? w : h;
//設置壓縮比例
opt.inSampleSize=scale;
//再次進行解析Bitmap
opt.inJustDecodeBounds=false;
return BitmapFactory.decodeByteArray(bytes, 0, bytes.length, opt);
}
}
使用:
package com.tarena.musicclient.adapter;
import java.io.File;
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.Environment;
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;
//聲明任務集合
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);
//對workThread進行初始化
workThread=new Thread(){
public void run() {
//不斷輪循任務集合
while(isLoop){
//如果任務集合不是空集
if(!tasks.isEmpty()){
//獲取任務對象並且發送請求
ImageLoadTask task = tasks.remove(0);
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{
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));
//向文件緩存中存儲圖片
//cacheDir: /data/data/com.xxx.client/cache/
//path: images/xxxx.jpg
File targetFile=new File(context.getCacheDir(), path);
BitmapUtils.save(targetFile, 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 position, View convertView, ViewGroup parent) {
ViewHolder holder=null;
if(convertView==null){
convertView=inflater.inflate(R.layout.item_lv_music, null);
holder=new ViewHolder();
holder.ivAlbum=(ImageView)convertView.findViewById(R.id.imageView1);
holder.tvName=(TextView)convertView.findViewById(R.id.tvName);
holder.tvDuration=(TextView)convertView.findViewById(R.id.tvDuration);
holder.tvSinger=(TextView)convertView.findViewById(R.id.tvSinger);
holder.tvAuthor=(TextView)convertView.findViewById(R.id.tvAuthor);
convertView.setTag(holder);
}
holder=(ViewHolder)convertView.getTag();
//給控件賦值
Music music=musics.get(position);
holder.tvName.setText(music.getName());
holder.tvSinger.setText(music.getSinger());
holder.tvAuthor.setText(music.getAuthor());
holder.tvDuration.setText(music.getDurationtime());
//給當前item中的ImageView設置一個Tag
//用於圖片下載完成後根據該tag
//找到相應的ImageView
holder.ivAlbum.setTag(position);
Bitmap bitmap=getCacheBitmap(music.getAlbumpic());
if(bitmap!=null){
holder.ivAlbum.setImageBitmap(bitmap);
return convertView;
}
//下載一張圖片
//向任務隊列中添加一個圖片任務
ImageLoadTask task=new ImageLoadTask();
//albumPic: images/xxxxx.jpg
task.path=music.getAlbumpic();
task.position=position;
tasks.add(task);
//喚醒工作線程 起來幹活
notifyWorkThread();
return convertView;
}
private Bitmap getCacheBitmap(String path){
//查詢緩存中是否有圖片 如果有 則直接獲取
SoftReference<Bitmap> ref=cache.get(path);
if(ref!=null && ref.get()!=null){
Bitmap bitmap=ref.get();
System.out.println("從緩存中讀取圖片..");
return bitmap;
}
//查詢文件緩存
File targetFile=new File(context.getCacheDir(), path);
Bitmap bitmap;
try {
bitmap = BitmapUtils.loadBitmap(targetFile.getAbsolutePath());
//如果文件中查到了bitmap
//那麼存入內存緩存
if(bitmap!=null){
System.out.println("從文件緩存中讀取圖片..");
cache.put(path, new SoftReference<Bitmap>(bitmap));
}
return bitmap;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/**
* 喚醒工作線程
*/
public void notifyWorkThread(){
synchronized (workThread) {
workThread.notify();
}
}
class ImageLoadTask{
String path;
Bitmap bitmap;
int position;
}
class ViewHolder{
ImageView ivAlbum;
TextView tvName;
TextView tvDuration;
TextView tvSinger;
TextView tvAuthor;
}
public void stopWorkThread() {
isLoop=false;
notifyWorkThread();
}
}