1.回顾
上篇 学习了,关于 异步任务的知识;
2.重点
(1)GridView Adapter实现
(2)LruCache 缓存实现
(3)异步加载 Thread + Handler 实现
3.效果图
4.GridAdapter实现
Adapter的实现不解释,前面用了很多了;
注意:耗时操作不能放在 getView 中执行!
package com.example.Adapter;
import java.util.List;
import android.annotation.SuppressLint;
import android.content.Context;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.TextView;
import com.example.asynctask.R;
public class GridAdapter extends BaseAdapter {
private List<MoviesIfo> movies;
private Context context;
private ViewHolder holder;
public GridAdapter(List<MoviesIfo> movies, Context context) {
// 数据
this.movies = movies;
this.context = context;
}
@Override
public int getCount() {
// TODO Auto-generated method stub
return movies.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return movies.get(position);
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@SuppressLint("ViewHolder")
@Override
public View getView(int position, View convertView, ViewGroup parent) {
MoviesIfo ifo = movies.get(position);
// 加载 布局 并 设置 布局
holder = new ViewHolder();
convertView = View.inflate(context, R.layout.gridlist_item, null);
holder.list_image = (ImageView) convertView
.findViewById(R.id.list_image);
holder.list_tvname = (TextView) convertView
.findViewById(R.id.list_tvname);
holder.list_tvtotle = (TextView) convertView
.findViewById(R.id.list_tvtotle);
// 设置图片
holder.list_image.setScaleType(ScaleType.FIT_XY);
holder.list_image.setImageResource(R.drawable.tubiao);
holder.list_tvname.setText(ifo.getName());
holder.list_tvtotle.setText("给力的电影 id= " + ifo.getId());
// ReqeustImageByThread reqeustImage = new
// ReqeustImageByThread(ifo.getPic(),
// holder.list_image);
// reqeustImage.start();
RequestImageByRunnable requestImageByRunnable = new RequestImageByRunnable(
ifo.getPic(), holder.list_image);
requestImageByRunnable.RequestImage();
return convertView;
}
class ViewHolder {
public ImageView list_image;
public TextView list_tvname, list_tvtotle;
}
}
5. 单例模式 封装 LruCache 缓存类
package com.example.Adapter;
import java.util.ArrayList;
import java.util.List;
import android.graphics.Bitmap;
import android.support.v4.util.LruCache;
public class ImageCache {
/**
* 缓存类 LruCache
*/
private static LruCache<String,Bitmap> imgCache;
/**
* 实例
*/
private static ImageCache instance;
/**
* 判断key 是否存在
*/
private static List<String> lruKeys;
public ImageCache() {
// 初始化 ,拿可用 内存的8分之一
int maxMemory=(int) Runtime.getRuntime().maxMemory();
int cacheMemory=maxMemory/8;
imgCache=new LruCache<String, Bitmap>(cacheMemory);
lruKeys=new ArrayList<String>();
}
/**
* 单例模式 创建 ImageCache 缓存类
* @return
*/
public static ImageCache getinstance(){
if(instance==null){
instance=new ImageCache();
return instance;
}else{
return instance;
}
}
/**
* 添加缓存
* @param key
* @param bitmap
*/
public void setCache(String key,Bitmap bitmap){
imgCache.put(key, bitmap);
lruKeys.add(key);
}
/**
* 得到缓存
* @param key
* @return
*/
public Bitmap getCache(String key){
return imgCache.get(key);
}
/**
* 判断是否存在key
* @param key
* @return
*/
public boolean isKey(String key){
return lruKeys.contains(key);
}
}
6.异步加载 Thread + Handler
package com.example.Adapter;
import com.example.Http.UrlConnGetdata;
import com.example.asynctask.R;
import android.graphics.Bitmap;
import android.os.Handler;
import android.os.Message;
import android.widget.ImageView;
public class ReqeustImageByThread extends Thread{
/**
* 请求图片
*
* 一个图片请求 对应一个 Thread
*
*/
private final String baseUrl="http://192.168.75.1:8081/GoodsServers/";
private String url;
private ImageView imageView;
public ReqeustImageByThread(String url,ImageView imageView) {
//
this.url=baseUrl+url;
this.imageView=imageView;
}
private Bitmap getBitmap(String picpath){
return UrlConnGetdata.getBitmap(url);
}
Handler handler=new Handler(){
public void handleMessage(android.os.Message msg) {
Bitmap bitmap=(Bitmap) msg.obj;
imageView.setTag(url);
if(bitmap!=null){
imageView.setImageBitmap(bitmap);
}else{
imageView.setImageResource(R.drawable.fail);
}
};
};
@Override
public void run() {
//执行网络请求
Bitmap bitmap=null;
ImageCache imageCache=ImageCache.getinstance();
if(imageCache.isKey(url)){
//如果 存在 ,去内存中的
bitmap=imageCache.getCache(url);
}else{
//否则 ,请求 图片
bitmap=getBitmap(url);
imageCache.setCache(url, bitmap);
}
Message msg=handler.obtainMessage();
msg.obj=bitmap;
handler.sendMessage(msg);
}
}
7.加载图片
图片压缩和图片请求的看前几篇文章!
/**
* 加载单张图片
* @return
*/
public static Bitmap getBitmap(String imgPath){
try {
URL url=new URL(imgPath);
HttpURLConnection conn=(HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);
conn.setUseCaches(false);
InputStream is=conn.getInputStream();
Bitmap bitmap=BitmapFactory.decodeStream(is);
//质量压缩
//bitmap=PictureUtil.compressImage(bitmap);
return bitmap;
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
8.总结
(1)不管是 ListView 还是 GridView ,在用的时候,必须使用 设置 setTag() , 否则 产生图片错位现象;
(2)当然 缓存也很重要,lruCache 可以轻松实现 图片缓存;用到的缓存技术还有文件缓存,内存缓存等;
(3)还有的是 加载优化,比如 当用户滑动到 屏幕上的几条数据的时候,再去加载这些图片!