/**
* author:Created by WangZhiQiang on 2017-09-04.
* 工具类,把对url进行md5加密,加密后以字符串的形式返回;
* 缓存的时候用key(url加密后的字符串)对应value(bitmap)
*/
public class EncoderUtils {
/**
* Md5Encoder
*
* @param string
* @return
* @throws Exception
*/
public static String encode(String string) throws Exception {
byte[] hash = MessageDigest.getInstance("MD5").digest(
string.getBytes("UTF-8"));
StringBuilder hex = new StringBuilder(hash.length * 2);
for (byte b : hash) {
if ((b & 0xFF) < 0x10) {
hex.append("0");
}
hex.append(Integer.toHexString(b & 0xFF));
}
return hex.toString();
}
}
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.LruCache;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* author:Created by WangZhiQiang on 2017-09-04.
* 处理三级缓存
* 内存缓存(LruCache-->最近最少使用算法,当缓存慢的时候,自动把最近使用最少的删除,腾出来的空间添加新的缓存内容)
* sd卡缓存
* 网络
*/
public class ImagesUtils {
Handler handler;
private File cacheDir;
private ExecutorService newFixedThreadPool;
private LruCache<String, Bitmap> lruCache;
/**
* @param context
* @param handler
*/
public ImagesUtils(Context context, Handler handler) {
//获得你手机上的最大内存
long maxMemory = Runtime.getRuntime().maxMemory();
int maxSize = (int) (maxMemory / 8);
this.handler = handler;
//得到本app在sd上的缓存文件夹
cacheDir = context.getCacheDir();
// 初始化线程池;初始化5个现成,供程序使用
newFixedThreadPool = Executors.newFixedThreadPool(5);
lruCache = new LruCache<String, Bitmap>(maxSize) {
//每次缓存图片都要调用这个方法;
@Override
protected int sizeOf(String key, Bitmap value) {
return value.getRowBytes() * value.getHeight();
}
};
}
/**
* 取图片,
*
* @param path
* @return
*/
public Bitmap getBitMap(String path) {
Bitmap bitmap = lruCache.get(path);
if (bitmap != null) {
System.out.println("我走了内存");
return bitmap;
}
//从本直去取,sd卡去取bitmap
bitmap = getBitMapFromLocal(path);
if (bitmap != null) {
System.out.println("我走了本地缓存");
return bitmap;
}
// 从网络去取
getBitmapFromNet(path);
return null;
}
/**
* 从sd卡获取图片
*
* @param path
* @return
*/
private Bitmap getBitMapFromLocal(String path) {
try {
String encode = EncoderUtils.encode(path);
FileInputStream fileInputStream = new FileInputStream(cacheDir
+ "/" + encode);
Bitmap bitmap = BitmapFactory.decodeStream(fileInputStream);
//存到内存
lruCache.put(path, bitmap);
return bitmap;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 从网络
*
* @param path
*/
private void getBitmapFromNet(final String path) {
//用线程池里的线程执行请求网络操作;
newFixedThreadPool.execute(new Runnable() {
@Override
public void run() {
try {
URL url = new URL(path);
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);
int responseCode = connection.getResponseCode();
if (responseCode == 200) {
InputStream inputStream = connection.getInputStream();
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
Message msg = new Message();
msg.what = 111;
msg.obj = bitmap;
Bundle data = new Bundle();
data.putString("tag", path);
msg.setData(data);
handler.sendMessage(msg);
//缓存到本地
saveBitmapToLocal(bitmap, path);
//缓存到内存
lruCache.put(path, bitmap);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
protected void saveBitmapToLocal(Bitmap bitmap, String path) {
try {
String encode = EncoderUtils.encode(path);
FileOutputStream fileOutputStream = new FileOutputStream(cacheDir + "/" + encode);
//图片二次裁剪
bitmap.compress(Bitmap.CompressFormat.JPEG, 80, fileOutputStream);
} catch (Exception e) {
e.printStackTrace();
}
}
}
import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
public class MainActivity extends AppCompatActivity {
private GridView gv;
ImagesUtils imagUtils;
String[] imageUrls = new String[] {
"https://img-my.csdn.net/uploads/201407/26/1406383291_8239.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406383290_9329.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406383290_1042.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406383275_3977.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406383265_8550.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406383264_3954.jpg",
"https://img-my.csdn.net/uploads/201407/26/1406383264_4787.jpg",
};
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what == 0) {
Bitmap bitmap = (Bitmap) msg.obj;
// 设置给imageView
String tag = msg.getData().getString("tag");
// 根据标记取出imageView
ImageView imageView = (ImageView) gv.findViewWithTag(tag);
if (imageView != null && bitmap != null) {
// 从网络获取图片
imageView.setImageBitmap(bitmap);
Log.i("tag", "从网络中获取图片");
}
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imagUtils = new ImagesUtils(this,handler);
gv = (GridView) findViewById(R.id.gv);
gv.setAdapter(new MyAdapter());
}
class MyAdapter extends BaseAdapter {
@Override
public int getCount() {
// TODO Auto-generated method stub
return imageUrls.length;
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView iv = new ImageView(MainActivity.this);
iv.setTag(imageUrls[position]);
//去图片;
Bitmap bitmap = imagUtils.getBitMap(imageUrls[position]);
// 从内存中或者缓存中
if (bitmap != null) {
iv.setImageBitmap(bitmap);
}
// 获取图片
return iv;
}
}
}
加载权限
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>