首先用sp将json数据保存起来,然后将网络数据分别存储在内存、本地。
PhotosMenuDetailPager.java
PhotosMenuDetailPager extends MenuDetailBasePager {
@ViewInject(R.id.lv_photos)
private ListView mListView;
@ViewInject(R.id.gv_photos)
private GridView mGridView;
private List<PhotoItemBean> photoItemList;
private BitmapUtils bitmapUtils;
private boolean isSingleColumns = true; // 当前是否是单列数据, 默认是单列
private BitmapCacheUtils mBitmapCacheUtils; // 图片缓存工具类
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case NetCacheUtils.SUCCESS: // 网络缓存请求成功.
Bitmap bm = (Bitmap) msg.obj;
int position = msg.arg1;
ImageView mImageView = (ImageView) mListView.findViewWithTag(position);
if(mImageView != null) {
// System.out.println("当前是第" + position + "张, 图片请求成功");
mImageView.setImageBitmap(bm);
}
break;
case NetCacheUtils.FAILED:
Toast.makeText(mActivity, "第" + msg.arg1 + "张图片请求失败", 0).show();
break;
default:
break;
}
}
};
public PhotosMenuDetailPager(Activity activity) {
super(activity);
// bitmapUtils = new BitmapUtils(mActivity);
// bitmapUtils.configDefaultBitmapConfig(Config.ARGB_4444);
mBitmapCacheUtils = new BitmapCacheUtils(handler);
}
@Override
public View initView() {
View view = View.inflate(mActivity, R.layout.photos, null);
ViewUtils.inject(this, view);
return view;
}
@Override
public void initData() {
// 先显示缓存起来的数据
String json = CacheUtils.getString(mActivity, ConstantUtils.PHOTOS_URL, null);
if(!TextUtils.isEmpty(json)) {
processData(json);
}
// 去网络中取图片数据
getDataFromNet();
}
private void getDataFromNet() {
HttpUtils httpUtils = new HttpUtils();
httpUtils.send(HttpMethod.GET, ConstantUtils.PHOTOS_URL, new RequestCallBack<String>() {
@Override
public void onSuccess(ResponseInfo<String> responseInfo) {
// System.out.println("组图数据请求成功: " + responseInfo.result);
CacheUtils.putString(mActivity, ConstantUtils.PHOTOS_URL, responseInfo.result);
processData(responseInfo.result);
}
@Override
public void onFailure(HttpException error, String msg) {
System.out.println("组图数据请求失败: " + msg);
}
});
}
/** * 处理和显示数据 * @param result */
protected void processData(String json) {
PhotosBean bean = parseJson(json);
photoItemList = bean.data.news;
PhotosAdapter mAdapter = new PhotosAdapter();
mListView.setAdapter(mAdapter);
}
/** * 解析json数据 * @param json * @return */
private PhotosBean parseJson(String json) {
Gson gson = new Gson();
return gson.fromJson(json, PhotosBean.class);
}
class PhotosAdapter extends BaseAdapter {
@Override
public int getCount() {
return photoItemList.size();
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
PhotosViewHolder mHolder = null;
if(convertView == null) {
convertView = View.inflate(mActivity, R.layout.photos_item, null);
mHolder = new PhotosViewHolder();
mHolder.ivImage = (ImageView) convertView.findViewById(R.id.iv_photos_item_iamge);
mHolder.tvDescription = (TextView) convertView.findViewById(R.id.tv_photos_item_description);
convertView.setTag(mHolder);
} else {
mHolder = (PhotosViewHolder) convertView.getTag();
}
PhotoItemBean bean = photoItemList.get(position);
// 根据mholder的两个对象进行赋值
mHolder.tvDescription.setText(bean.title);
// 设置默认图片
mHolder.ivImage.setTag(position);
mHolder.ivImage.setImageResource(R.drawable.pic_item_list_default);
// 设置最新图片,之前设置的是默认图片,这里从网络请求图片后设置背景
// bitmapUtils.display(mHolder.ivImage, bean.listimage);
Bitmap bm = mBitmapCacheUtils.getBitmapFromUrl(bean.listimage, position);
if(bm != null) {
// 当前图片不等于null, 是从内存或者本地中取到的, 立刻显示.
mHolder.ivImage.setImageBitmap(bm);
}
return convertView;
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return null;
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
}
public class PhotosViewHolder {
public ImageView ivImage;
public TextView tvDescription;
}
/** * 切换当前的页面显示. */
public void switchListOrGrid(ImageButton ib) {
if(isSingleColumns) {
isSingleColumns = false;
// 当前是单列, 切换成两列
mListView.setVisibility(View.GONE);
mGridView.setVisibility(View.VISIBLE);
mGridView.setAdapter(new PhotosAdapter());
// 切换图片
ib.setImageResource(R.drawable.icon_pic_list_type);
} else {
isSingleColumns = true;
// 当前是两列, 切换成单列
mGridView.setVisibility(View.GONE);
mListView.setVisibility(View.VISIBLE);
mListView.setAdapter(new PhotosAdapter());
// 切换图片
ib.setImageResource(R.drawable.icon_pic_grid_type);
}
}
}
BitmapCacheUtils.java
/** * @author andong * 图片缓存工具类 */
public class BitmapCacheUtils {
private NetCacheUtils mNetCacheUtils; // 网络缓存对象
private LocalCacheUtils mLocalCacheUtils; // 本地缓存对象
private MemoryCacheUtils mMemoryCacheUtils; // 内存缓存对象
public BitmapCacheUtils(Handler handler) {
mMemoryCacheUtils = new MemoryCacheUtils();
mLocalCacheUtils = new LocalCacheUtils();
mNetCacheUtils = new NetCacheUtils(handler, mLocalCacheUtils, mMemoryCacheUtils);
}
/** * 根据Url取图片 * * 1. 先根据Url去内存中取, 如果取到直接返回. * 2. 再根据Url去本地中取, 如果取到直接返回. * 3. 最后去网络中取, 取到之后发送给主线程显示. * 3.1 根据Url, 向内存中存一份. * 3.2 根据Url, 向本地中存一份. * * @param imageUrl * @return */
public Bitmap getBitmapFromUrl(String imageUrl, int position) {
// 1. 先根据Url去内存中取, 如果取到直接返回.
Bitmap bm = mMemoryCacheUtils.getBitmapFromMemory(imageUrl);
if(bm != null) {
System.out.println("从内存中取到的");
return bm;
}
// 2. 再根据Url去本地中取, 如果取到直接返回.
bm = mLocalCacheUtils.getBitmapFromLocal(imageUrl);
if(bm != null) {
System.out.println("从本地中取到的");
return bm;
}
// 3. 最后去网络中取, 取到之后发送给主线程显示.
System.out.println("从网络中取到的");
mNetCacheUtils.getBitmapFromNet(imageUrl, position);
return null;
}
}
MemoryCacheUtils.java
public class MemoryCacheUtils {
private LruCache<String, Bitmap> mMemoryCache;
public MemoryCacheUtils() {
// 虚拟机内存的8分之一来缓存图片
int maxMemorySize = (int) (Runtime.getRuntime().maxMemory() / 8);
mMemoryCache = new LruCache<String, Bitmap>(maxMemorySize) {
/** * 把图片的大小返回 */
@Override
protected int sizeOf(String key, Bitmap value) {
return value.getRowBytes() * value.getHeight();
}
};
}
/** * 向内存中存一张图片 * @param imageUrl * @param bm */
public void putBitmap2Memory(String imageUrl, Bitmap bm) {
mMemoryCache.put(imageUrl, bm);
}
/** * 从内存中取一张图片 * @param imageUrl * @return */
public Bitmap getBitmapFromMemory(String imageUrl) {
return mMemoryCache.get(imageUrl);
}
}
LocalCacheUtils.java
/** * @author andong * 本地缓存工具类 */
public class LocalCacheUtils {
// 缓存的目录
private final String CACHE_DIR = "/mnt/sdcard/itheima_zhbj";
/** * 根据Url存储当前图片 * @param imageUrl * @param bm */
public void putBitmap2Local(String imageUrl, Bitmap bm) {
try {
String fileName = MD5Encoder.encode(imageUrl);
File file = new File(CACHE_DIR, fileName); // /mnt/sdcard/it/aslkjdlhk124312423lkj
File parentFile = file.getParentFile();
if(!parentFile.exists()) {
parentFile.mkdirs();
}
FileOutputStream fos = new FileOutputStream(file);
// 把图片通过流写到本地
bm.compress(CompressFormat.JPEG, 100, fos);
} catch (Exception e) {
e.printStackTrace();
}
}
/** * 从本地中根据url取出图片 * @param imageUrl * @return */
public Bitmap getBitmapFromLocal(String imageUrl) {
try {
String fileName = MD5Encoder.encode(imageUrl);
File file = new File(CACHE_DIR, fileName); // /mnt/sdcard/itheima_zhbj/aslkjdlhk124312423lkj
if(file.exists()) {
// 文件存在, 有缓存, 读取出来, 并返回
FileInputStream is = new FileInputStream(file);
Bitmap bm = BitmapFactory.decodeStream(is);
return bm;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
NetCacheUtils.java
/** * @author andong * 网络缓存工具类 */
public class NetCacheUtils {
public static final int SUCCESS = 0;
public static final int FAILED = 1;
private Handler handler;
private ExecutorService mExecutorService;
private LocalCacheUtils localCacheUtils; // 本地缓存对象
private MemoryCacheUtils memoryCacheUtils; // 内存缓存对象
public NetCacheUtils(Handler handler, LocalCacheUtils localCacheUtils, MemoryCacheUtils memoryCacheUtils) {
this.handler = handler;
this.localCacheUtils = localCacheUtils;
this.memoryCacheUtils = memoryCacheUtils;
// 创建一个线程池
mExecutorService = Executors.newFixedThreadPool(10);
}
/** * 使用子线程去请求网络, 把图片抓取回来, 再发送给主线程 * @param imageUrl */
public void getBitmapFromNet(String imageUrl, int position) {
// new Thread(new InternalRunnable(imageUrl, position)).start();
// 让线程池执行一个任务.
mExecutorService.execute(new InternalRunnable(imageUrl, position));
}
class InternalRunnable implements Runnable {
private String imageUrl;
private int position;
public InternalRunnable(String imageUrl, int position) {
this.imageUrl = imageUrl;
this.position = position;
}
@Override
public void run() {
HttpURLConnection conn = null;
try {
conn = (HttpURLConnection) new URL(imageUrl).openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);
conn.setReadTimeout(5000);
conn.connect();
int responseCode = conn.getResponseCode();
if(responseCode == 200) {
InputStream is = conn.getInputStream();
Bitmap bm = BitmapFactory.decodeStream(is);
// 发送到主线程中显示
Message msg = handler.obtainMessage();
msg.obj = bm;
msg.what = SUCCESS;
msg.arg1 = position;
handler.sendMessage(msg);
// 向内存存一份
memoryCacheUtils.putBitmap2Memory(imageUrl, bm);
// 向本地存一份
localCacheUtils.putBitmap2Local(imageUrl, bm);
}
} catch (Exception e) {
e.printStackTrace();
Message msg = handler.obtainMessage();
msg.what = FAILED;
msg.arg1 = position;
handler.sendMessage(msg);
} finally {
if(conn != null) {
conn.disconnect(); // 断开连接
}
}
}
}
}