1.加载网络图片的方法
public Bitmap getImageBitmap(String url) {
Bitmap bitmap =null ;
try {
URL imgUrl = new URL(url);
HttpURLConnection conn = (HttpURLConnection) imgUrl
.openConnection();
conn.connect();
InputStream is = conn.getInputStream();
bitmap = BitmapFactory.decodeStream(is);
is.close();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return bitmap;
}
2.主线程调用
new Thread(new Runnable() {
@Override
public void run() {
final Bitmap bitmap=getImageBitmap(imageUrl);
runOnUiThread(new Runnable() {
@Override
public void run() {
iv_glide.setImageBitmap(bitmap);
}
});
}
}).start();
3.效果预览
20190414100022.jpg4图片占用内存
20190414101737.jpg图片实际大小4M
当前存在的问题
- 没有线程管理
- 复用不方便
- 没有使用缓存机制,每次加载都从网络获取,消耗用户流量和加载慢
+图片占用空间还有优化的空间
+关闭输入输出流
优化调用
public static void getImageBitmap(final String url, final ImageView imageView, final Context context) {
new Thread(new Runnable() {
@Override
public void run() {
final Bitmap bitmap ;
InputStream is=null;
try {
URL imgUrl = new URL(url);
HttpURLConnection conn = (HttpURLConnection) imgUrl
.openConnection();
conn.connect();
is = conn.getInputStream();
bitmap = BitmapFactory.decodeStream(is);
((Activity)context).runOnUiThread(new Runnable() {
@Override
public void run() {
imageView.setImageBitmap(bitmap);
}
});
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if(is!=null){
try {
is.close();
}catch (Exception e){
e.printStackTrace();
}
}
}
}
}).start();
}
新建一个工具类
ImageLoaderUtils.getImageBitmap(imageUrl,iv_glide,this);
直接调用
增加线程管理
public static void getImageBitmap(final String url, final ImageView imageView, final Context context) {
// ThreadPoolExecutor threadPoolExecutor=new ThreadPoolExecutor(5,7,60*1000,TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(3));
ExecutorService executorService = new ThreadPoolExecutor(NUMBER_OF_CORES, NUMBER_OF_CORES*2, KEEP_ALIVE_TIME, KEEP_ALIVE_TIME_UNIT, taskQueue);
executorService.execute(new Runnable() {
@Override
public void run() {
final Bitmap bitmap ;
InputStream is=null;
try {
URL imgUrl = new URL(url);
HttpURLConnection conn = (HttpURLConnection) imgUrl
.openConnection();
conn.connect();
is = conn.getInputStream();
bitmap = BitmapFactory.decodeStream(is);
((Activity)context).runOnUiThread(new Runnable() {
@Override
public void run() {
imageView.setImageBitmap(bitmap);
}
});
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if(is!=null){
try {
is.close();
}catch (Exception e){
e.printStackTrace();
}
}
}
}
});
使用缓存
内存缓存和磁盘缓存
public static int maxMemory = (int) (Runtime.getRuntime().maxMemory() /1024);
final int cacheSize = maxMemory / 8;
public static int NUMBER_OF_CORES = Runtime.getRuntime().availableProcessors();
public static int KEEP_ALIVE_TIME = 1;
public static TimeUnit KEEP_ALIVE_TIME_UNIT = TimeUnit.SECONDS;
public static BlockingQueue <Runnable> taskQueue = new LinkedBlockingQueue <Runnable>();
private LruCache <String, Bitmap> mCaches;
private static ExecutorService executorService;
private static ImageLoaderUtils imageLoaderUtils;
private DiskLruCache diskLruCache;
private ImageLoaderUtils(Context context){
mCaches = new LruCache<String, Bitmap>(cacheSize) {
@Override
protected int sizeOf(String key, Bitmap value) {
//判断添加进入的value的占用内存的大小
//这里默认sizeOf是返回1,不占用,内存会不够用,所以要给它一个具体占用内存的大小
// return super.sizeOf(key, value);
//获取Bitmap的大小
System.out.println("value.getRowBytes() * value.getHeight()/1024=="+value.getRowBytes() * value.getHeight()/1024);
return value.getRowBytes() * value.getHeight()/1024;
}
};
/**
* 初始化硬盘缓存DiskLruCahce
*/
// 获取硬盘缓存路径,参数二为所在缓存路径的文件夹名称
File directory = getDiskCacheDir(context, "bitmap");
if (!directory.exists()) {
// 若文件夹不存在,建立文件夹
directory.mkdirs();
}
int appVersion = getAppVersion(context);
try {
// 参数1:缓存文件路径,参数2:系统版本号,参数3:一个缓存路径对于几个文件,参数4:缓存空间大小:字节
diskLruCache = DiskLruCache.open(directory, appVersion, 1, 1024 * 1024 * 50);
} catch (IOException e) {
e.printStackTrace();
}
executorService = new ThreadPoolExecutor(NUMBER_OF_CORES, NUMBER_OF_CORES * 2, KEEP_ALIVE_TIME, KEEP_ALIVE_TIME_UNIT, taskQueue);
}
public static ImageLoaderUtils getImageLoaderUtils(Context context){
if(imageLoaderUtils==null) {
imageLoaderUtils = new ImageLoaderUtils(context);
}
return imageLoaderUtils;
}
public void getImageBitmap(final String url, final ImageView imageView, final Context context) {
// ThreadPoolExecutor threadPoolExecutor=new ThreadPoolExecutor(5,7,60*1000,TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(3));
System.out.println("maxMemory===" + maxMemory);
Bitmap bitmapCache = mCaches.get(url);
if(bitmapCache!=null){
imageView.setImageBitmap(bitmapCache);
System.out.println("Memory=="+url);
return;
}
try {
String key = hashKeyFromUrl(url);
DiskLruCache.Snapshot snapShot = diskLruCache.get(key);
if (snapShot != null) {
InputStream is = snapShot.getInputStream(0);
Bitmap bitmap = BitmapFactory.decodeStream(is);
System.out.println("diskLruCache==");
imageView.setImageBitmap(bitmap);
mCaches.put(url, bitmap);
return;
}
}catch (Exception e){
e.printStackTrace();
}
executorService.execute(new Runnable() {
@Override
public void run() {
final Bitmap bitmap;
InputStream is = null;
try {
URL imgUrl = new URL(url);
HttpURLConnection conn = (HttpURLConnection) imgUrl
.openConnection();
conn.connect();
is = conn.getInputStream();
bitmap = BitmapFactory.decodeStream(is);
mCaches.put(url, bitmap);
String key= hashKeyFromUrl(url);
DiskLruCache.Editor editor = diskLruCache.edit(key);
if (editor != null) {
OutputStream outputStream = editor.newOutputStream(0);
if (downloadUrlToStream(url, outputStream)) {
editor.commit();
} else {
editor.abort();
}
}
diskLruCache.flush();
((Activity) context).runOnUiThread(new Runnable() {
@Override
public void run() {
imageView.setImageBitmap(bitmap);
}
});
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (is != null) {
try {
is.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
});}
private String hashKeyFromUrl(String url){
String cacheKey="";
try {
MessageDigest messageDigest=MessageDigest.getInstance("MD5");
messageDigest.update(url.getBytes());
cacheKey=bytesToHexString(messageDigest.digest());
}
catch (Exception e){
e.printStackTrace();
}
return cacheKey;}
private String bytesToHexString(byte[] bytes){
StringBuilder stringBuilder=new StringBuilder();
for (int i=0;i<bytes.length;i++){
String hex=Integer.toHexString(0xFF & bytes[i]);
if(hex.length()==1){
stringBuilder.append('0');
}
stringBuilder.append(hex);
}
return stringBuilder.toString();}
/**
* @param context
* @param uniqueName
* @return
* 当SD卡存在或者SD卡不可被移除的时候,就调用getExternalCacheDir()方法来获取缓存路径,否则就调用getCacheDir
* ()方法来获取缓存路径。 前者获取到的就是 /sdcard/Android/data/<application
* package>/cache 这个路径 而后者获取到的是 datadata/application package>/cache
* 这个路径。
*/
public File getDiskCacheDir(Context context, String uniqueName) {
String cachePath;
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) || !Environment.isExternalStorageRemovable()) {
cachePath = context.getExternalCacheDir().getPath();
} else {
cachePath = context.getCacheDir().getPath();
}
return new File(cachePath + File.separator + uniqueName);
}
/**
* @param context
* @return 获取系统版本号
*/
public int getAppVersion(Context context) {
try {
PackageInfo info = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
return info.versionCode;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
return 1;
}
private boolean downloadUrlToStream(String urlString, OutputStream outputStream) {
HttpURLConnection urlConnection = null;
BufferedOutputStream out = null;
BufferedInputStream in = null;
try {
final URL url = new URL(urlString);
urlConnection = (HttpURLConnection) url.openConnection();
in = new BufferedInputStream(urlConnection.getInputStream(), 8 * 1024);
out = new BufferedOutputStream(outputStream, 8 * 1024);
int b;
while ((b = in.read()) != -1) {
out.write(b);
}
return true;
} catch (final IOException e) {
e.printStackTrace();
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
try {
if (out != null) {
out.close();
}
if (in != null) {
in.close();
}
} catch (final IOException e) {
e.printStackTrace();
}
}
return false;
}
还有遗留的问题
- 图片压缩
- 同一网址图片资源发生变化后
- 多线程
图片压缩
网友评论