public class Main extends Activity {
/*LruCache,它的主要算法原理是把最近使用的对象用强引用存储在 LinkedHashMap 中,
* 并且把最近最少使用的对象在缓存值达到预设定值之前从内存中移除。
* 在过去,我们经常会使用一种非常流行的内存缓存技术的实现,即软引用或弱引用 (SoftReference or WeakReference)。
* 但是现在已经不再推荐使用这种方式了,因为从 Android 2.3 (API Level 9)开始,
* 垃圾回收器会更倾向于回收持有软引用或弱引用的对象,这让软引用和弱引用变得不再可靠。
* 另外,Android 3.0 (API Level 11)中,图片的数据会存储在本地的内存当中,因而无法用一种可预见的方式将其释放,
* 这就有潜在的风险造成应用程序的内存溢出并崩溃。*/
private GridView gridView;
private String[] urls;
private WallAdapter wallAdapter;
private ExecutorService pool = Executors.newFixedThreadPool(5);//创建线程池开启10条
@Override
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
gridView=(GridView)this.findViewById(R.id.gridview);
urls=ImagesUtil.imageThumbUrls;
wallAdapter=new WallAdapter(Main.this, urls, gridView);
gridView.setAdapter(wallAdapter);
}
public class WallAdapter extends BaseAdapter implements OnScrollListener{
private LruCache<String, Bitmap> lruCache;//键String:代表图片的url,值Bitmap:存放的图片
private Context context;
private String[] urls;
private boolean isFirstIn=true;//是否第一次进入
private GridView gridView;
private Set<BitmapWorkTask> tasks;//存储正在下载和等待下载的任务
private int firstVisiableItemId;//可见区域的第一张图片的id
private int visiableCount;//可见区域的图片张数和
public WallAdapter(Context context,String[] urls,GridView gridView){
this.context=context;
this.urls=urls;
this.gridView=gridView;
tasks=new HashSet<BitmapWorkTask>();
int maxMemorry=(int)Runtime.getRuntime().maxMemory();
int size=maxMemorry/8;//最大内存的八分之一
lruCache=new LruCache<String, Bitmap>(size){
@Override
protected int sizeOf(String key, Bitmap value) {
Log.i("------------->", value.getByteCount()+"");
return value.getByteCount();
}
};
gridView.setOnScrollListener(this);
Log.i("------------>", "baseAdapter我在执行");
}
@Override
public int getCount() {
return urls.length;
}
@Override
public Object getItem(int position) {
return urls[position];
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View view, ViewGroup parent) {
if (view==null)
view=LayoutInflater.from(context).inflate(R.layout.gridview_item, null);
ImageView imageView=(ImageView)view.findViewById(R.id.imageview);
//给imageview做标记,避免异步加载图片乱序
imageView.setTag(urls[position]);
//图片的显示
setImageView(urls[position], imageView);
return view;
}
//监听GridView的状态,第一次进来的时候,不会调用
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
//处于停止状态才下载,滚动式停止下载
if (scrollState==SCROLL_STATE_IDLE) {
loadBitmap(firstVisiableItemId, visiableCount);
}else {
if (tasks!=null) {
taskCancel();//取消下载任务
}
}
}
//第一次进入,不会调用onScrollStateChanged方法
@Override
public void onScroll(AbsListView view, int firstVisibleItem,int visibleItemCount, int totalItemCount) {
Log.i("------------------>", "Onscroll在执行");
Log.i("可见项的总数", visibleItemCount+"");
this.firstVisiableItemId=firstVisibleItem;
this.visiableCount=visibleItemCount;
if (isFirstIn && visibleItemCount>0) {
loadBitmap(firstVisibleItem, visibleItemCount);
isFirstIn=false;
}
}
/**取消下载任务*/
private void taskCancel(){
for (BitmapWorkTask task : tasks) {
task.cancel(false);
}
}
/**图片的下载任务,只加载可见项*/
private void loadBitmap( int firstVisiableItemId,int visiableCount){
for (int i = firstVisiableItemId; i < firstVisiableItemId+visiableCount; i++) {
String imageurl=urls[i];
Bitmap bitmap=getBitmapFromLruCache(imageurl);
if (bitmap==null) {
BitmapWorkTask task=new BitmapWorkTask();
tasks.add(task);//将下载的任务保存至集合中,便于控制
// task.execute(imageurl);
task.executeOnExecutor(pool, imageurl);//结合线程池,提高加载速度
}else {
ImageView imageView=(ImageView)gridView.findViewWithTag(imageurl);
if (imageView!=null && bitmap!=null) {
imageView.setImageBitmap(bitmap);
}
}
}
}
/**异步类执行图片加载任务*/
private class BitmapWorkTask extends AsyncTask<String, Void, Bitmap>{
String imageurl;
@Override
protected Bitmap doInBackground(String... params) {
imageurl=params[0];
Bitmap tempBitmap=downloadBitmap(imageurl);
if (tempBitmap!=null) {
addBitmapToLruCache(imageurl, tempBitmap);//下载后保存至缓存
}
return tempBitmap;
}
@Override
protected void onPostExecute(Bitmap bitmap) {
ImageView imageView=(ImageView)gridView.findViewWithTag(imageurl);//通过Tag找到对应的ImageView控件
if (imageView!=null && bitmap!=null) {
imageView.setImageBitmap(bitmap);
}
tasks.remove(this);//下载完后移除当前对象
}
}
/**下载图片方法,返回Bitmap对象*/
private Bitmap downloadBitmap(String imageUrl){
try {
URL url=new URL(imageUrl);
try {
HttpURLConnection conn=(HttpURLConnection)url.openConnection();
conn.setRequestMethod("GET");
conn.setReadTimeout(5*1000);
conn.setDoInput(true);
conn.setDoOutput(true);
InputStream inputStream=conn.getInputStream();
Bitmap bitmap=BitmapFactory.decodeStream(inputStream);
return bitmap;
} catch (IOException e) {
e.printStackTrace();
System.out.println("图片加载失败");
}
} catch (MalformedURLException e) {
e.printStackTrace();
System.out.println("图片资源路径不存在");
}
return null;
}
/**图片的显示*/
private void setImageView(String imageUrl,ImageView imageView){
Bitmap bitmap=getBitmapFromLruCache(imageUrl);
if (bitmap!=null) {
imageView.setImageBitmap(bitmap);
}else {
imageView.setImageResource(R.drawable.defualt);//默认图片
}
}
/** 图片添加到LruCache中*/
private void addBitmapToLruCache(String key,Bitmap bitmap){
if (getBitmapFromLruCache(key)==null) {
lruCache.put(key, bitmap);
}
}
/**据图片key值(url)获得Bitmap对象*/
private Bitmap getBitmapFromLruCache(String key){
return lruCache.get(key);
}
}
//退出结束所有下载任务
@Override
protected void onDestroy() {
super.onDestroy();
wallAdapter.taskCancel();
}
}
以上是在看别人的博文所写的,但有所改进,AyncTask结合线程池运用加快加载速度。
关于android图片墙的学习
最新推荐文章于 2025-05-25 19:13:53 发布
