首先我们需要在配置androidmanifest.xml里面添加
<uses-permission android:name="android.permission.internet" />
在android应用中实现图片缓存和下载
在现代移动应用开发中,用户体验至关重要,特别是在图像加载方面。为了提高应用的响应速度和减少网络流量,我们通常采用缓存机制来存储下载的图片。本文将介绍如何在android中实现一个简单的图片缓存加载器,允许从网络下载图片并缓存到本地。
项目结构
我们将构建一个名为 imagecacheloader 的类,该类负责从url加载图片,并首先检查本地缓存。如果缓存不存在,则从网络下载图片。
使用
package com.example.dowhttppic;
import android.os.bundle;
import androidx.activity.edgetoedge;
import androidx.appcompat.app.appcompatactivity;
import androidx.core.graphics.insets;
import androidx.core.view.viewcompat;
import androidx.core.view.windowinsetscompat;
import android.os.bundle;
import android.widget.imageview;
import androidx.appcompat.app.appcompatactivity;
public class mainactivity extends appcompatactivity {
private imageview imageview;
private imagecacheloader imagecacheloader;
@override
protected void oncreate(bundle savedinstancestate) {
super.oncreate(savedinstancestate);
setcontentview(r.layout.activity_main);
imageview = findviewbyid(r.id.imageview);
// 初始化 imagecacheloader
imagecacheloader = new imagecacheloader(this);
// 加载图片
string imageurl = "图片链接";
imagecacheloader.loadimage(imageurl, imageview);
}
}代码解析
package com.example.dowhttppic;
import android.content.context;
import android.graphics.bitmap;
import android.graphics.bitmapfactory;
import android.os.handler;
import android.widget.imageview;
import java.io.file;
import java.io.fileoutputstream;
import java.io.inputstream;
import java.io.outputstream;
import java.net.httpurlconnection;
import java.net.url;
public class imagecacheloader {
private context context;
private handler handler = new handler(); // 用于处理ui线程更新
// 构造函数,接收上下文
public imagecacheloader(context context) {
this.context = context;
}
// 公共方法:加载图片,首先从缓存读取,如果没有则通过网络下载
public void loadimage(final string url, final imageview imageview) {
// 获取缓存目录
file cachedir = context.getcachedir();
string filename = getfilenamefromurl(url);
final file imagefile = new file(cachedir, filename);
// 如果本地有缓存,直接加载本地图片
if (imagefile.exists()) {
bitmap bitmap = bitmapfactory.decodefile(imagefile.getabsolutepath());
imageview.setimagebitmap(bitmap);
} else {
// 启动线程下载图片并缓存
new thread(new runnable() {
@override
public void run() {
bitmap bitmap = downloadimage(url);
if (bitmap != null) {
saveimagetocache(imagefile, bitmap);
// 更新ui,需在主线程中执行
handler.post(new runnable() {
@override
public void run() {
imageview.setimagebitmap(bitmap);
}
});
} else {
// 超时或下载失败时显示默认图片
handler.post(new runnable() {
@override
public void run() {
imageview.setimageresource(r.drawable.no_image_dow_http);
}
});
}
}
}).start();
}
}
// 从网络下载图片,添加超时机制
private bitmap downloadimage(string urlstring) {
bitmap bitmap = null;
try {
url url = new url(urlstring);
httpurlconnection connection = (httpurlconnection) url.openconnection();
connection.setconnecttimeout(5000); // 设置连接超时为5秒
connection.setreadtimeout(5000); // 设置读取超时为5秒
connection.connect();
int responsecode = connection.getresponsecode();
if (responsecode == httpurlconnection.http_ok) {
inputstream inputstream = connection.getinputstream();
bitmap = bitmapfactory.decodestream(inputstream);
inputstream.close();
}
} catch (exception e) {
e.printstacktrace();
}
return bitmap;
}
// 将下载的图片保存到本地缓存
private void saveimagetocache(file imagefile, bitmap bitmap) {
try {
outputstream outputstream = new fileoutputstream(imagefile);
bitmap.compress(bitmap.compressformat.png, 100, outputstream);
outputstream.flush();
outputstream.close();
} catch (exception e) {
e.printstacktrace();
}
}
// 根据url提取文件名
private string getfilenamefromurl(string url) {
return url.substring(url.lastindexof("/") + 1);
}
}关键功能解析
1. 图片加载方法
loadimage 方法是该类的核心,它负责加载指定url的图片。首先,它尝试从本地缓存读取图片,如果缓存存在,则直接使用缓存的图片;如果不存在,则启动一个新线程下载图片。
public void loadimage(final string url, final imageview imageview) {
file cachedir = context.getcachedir();
string filename = getfilenamefromurl(url);
final file imagefile = new file(cachedir, filename);
if (imagefile.exists()) {
bitmap bitmap = bitmapfactory.decodefile(imagefile.getabsolutepath());
imageview.setimagebitmap(bitmap);
} else {
new thread(new runnable() {
@override
public void run() {
bitmap bitmap = downloadimage(url);
if (bitmap != null) {
saveimagetocache(imagefile, bitmap);
handler.post(new runnable() {
@override
public void run() {
imageview.setimagebitmap(bitmap);
}
});
} else {
handler.post(new runnable() {
@override
public void run() {
imageview.setimageresource(r.drawable.no_image_dow_http);
}
});
}
}
}).start();
}
}2. 下载图片
downloadimage 方法使用 httpurlconnection 从给定url下载图片。它设置了连接和读取的超时,以避免长时间等待。
private bitmap downloadimage(string urlstring) {
bitmap bitmap = null;
try {
url url = new url(urlstring);
httpurlconnection connection = (httpurlconnection) url.openconnection();
connection.setconnecttimeout(5000);
connection.setreadtimeout(5000);
connection.connect();
int responsecode = connection.getresponsecode();
if (responsecode == httpurlconnection.http_ok) {
inputstream inputstream = connection.getinputstream();
bitmap = bitmapfactory.decodestream(inputstream);
inputstream.close();
}
} catch (exception e) {
e.printstacktrace();
}
return bitmap;
}3. 保存图片到缓存
saveimagetocache 方法将下载的图片以png格式保存到应用的缓存目录中。
private void saveimagetocache(file imagefile, bitmap bitmap) {
try {
outputstream outputstream = new fileoutputstream(imagefile);
bitmap.compress(bitmap.compressformat.png, 100, outputstream);
outputstream.flush();
outputstream.close();
} catch (exception e) {
e.printstacktrace();
}
}4. 文件名提取
getfilenamefromurl 方法从图片url中提取文件名,以便在缓存中使用。
private string getfilenamefromurl(string url) {
return url.substring(url.lastindexof("/") + 1);
}或者通过学习glide
到此这篇关于在android中高效管理图片加载的文章就介绍到这了,更多相关android图片加载内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论