Android 에서 비동기 로 그림 불 러 오기
오늘 프로젝트 를 할 때 비동기 로 그림 을 불 러 오 는 기능 이 있 습 니 다.간단 하지만 기록 해 보 세 요.멜 로 이전에 비동기 로 그림 을 불 러 오 는 것 은 모두 AsynTask 라 는 API 를 사 용 했 기 때 문 입 니 다.이 종 류 를 계속 하면 매우 간단 하고 편리 합 니 다.doInBackground()방법 에서 다운로드 논 리 를 실현 합 니 다.구체 적 으로 다음 과 같이 실현 합 니 다.
논리 구현:메모리 에서 먼저 읽 고 메모리 에 이 그림 이 있 으 면 직접 사용 합 니 다.메모리 가 sdcard 에서 읽 히 지 않 으 면 표시 합 니 다.sdcard 에 없 으 면 네트워크 에서 읽 습 니 다.메모리 에 캐 시 를 켜 는 것 은 인터넷 의 실현 을 참고 한 것 입 니 다.멜 로 는 여기 서 공유 하 는 프로그램 원숭이 들 에 게 감 사 드 립 니 다.
public class ImageDownloader extends AsyncTask<String, Integer, Object> {
private static final String TAG = "ImageDownloader";
// , ( , , ListView )
private Map<String, SoftReference<Drawable>> imageCache = new HashMap<String, SoftReference<Drawable>>();
/**
*
*/
private ImageView mImageView;
public ImageDownloader(ImageView image) {
mImageView = image;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected Object doInBackground(String... params) {
// Log.i("ImageDownloader", "loading image...");
String url = params[0];
Drawable drawable = null;
try {
if (!"".equals(url) && url != null) {
String fileName = url.hashCode()+".jpg";
//
if (imageCache.containsKey(fileName)) {
SoftReference<Drawable> softReference = imageCache.get(fileName);
drawable = softReference.get();
if (drawable != null) {
return drawable;
}
}
File dir = new File(FileConstant.IMAGE_FILE_PATH);
if (!dir.exists()) {
boolean m = dir.mkdirs();
}
File file = new File(dir, fileName);
if (file.exists() && file.length() > 0) {
Log.i(TAG, "load image from sd card");
// sdcard
drawable = readFromSdcard(file);
} else {
//file.createNewFile();
Log.i(TAG, "load image from network");
URL imageUrl = new URL(url);
// sdcard
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
saveImageFile(imageUrl, file);
drawable = Drawable.createFromStream(new FileInputStream(file), fileName);
}else{
//
drawable = Drawable.createFromStream(imageUrl.openStream(), fileName);
}
}
if(drawable!=null){
//
imageCache.put(fileName, new SoftReference<Drawable>(drawable));
}
}
} catch (Exception e) {
e.printStackTrace();
}
return drawable;
}
/**
* save image
*/
private void saveImageFile(URL url, File file) {
FileOutputStream out = null;
InputStream in = null;
try {
file.deleteOnExit();
out = new FileOutputStream(file);
in = url.openStream();
byte[] buf = new byte[1024];
int len = -1;
while((len = in.read(buf))!=-1){
out.write(buf, 0, len);
out.flush();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if(out!=null){
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(in!=null){
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* sdcard
*/
private Drawable readFromSdcard(File file) throws Exception {
FileInputStream in = new FileInputStream(file);
return Drawable.createFromStream(in, file.getName());
}
@Override
protected void onPostExecute(Object result) {
super.onPostExecute(result);
Drawable drawable = (Drawable) result;
if (mImageView != null && drawable != null) {
mImageView.setBackgroundDrawable(drawable);
}
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
}
@Override
protected void onCancelled() {
super.onCancelled();
}
}
사용 시:
ImageDownloader loader = new ImageDownloader(imageView);
loader.execute(url);
사실 이렇게 되면 위험 도 있 습 니 다.즉,이러한 종류의 실현 에 문제 가 있 습 니 다.예 를 들 어 매번 imageView 에 네트워크 에 있 는 그림 을 설정 할 때 이런 종류의 메모리 캐 시 를 사용 하지 않 은 것 이 바로 imageCache 입 니 다.Map
imageView 를 설정 할 때마다 new 이미지 다운 로 더 의 대상 이 되 었 기 때문에 모든 이미지 다운 로 더 대상 에는 하나의 imageCache 가 독립 되 어 있 습 니 다.
또한,AsynTask 도 하나의 스 레 드 입 니 다.매번 사용 할 때마다 하나의 스 레 드 를 열 어 그림 을 로드 합 니 다.스 레 드 개 수 를 표시 하지 않 았 습 니 다.스 레 드 수 는 제한 이 있 기 때 문 입 니 다.
그래서 멜 로 는 오늘 이 문 제 를 발 견 했 습 니 다.그래서 다른 사람의 실현 을 참고 하여 스 레 드 탱크 를 사 용 했 습 니 다.논리 도 위의 코드 와 같이 메모리 에서 먼저 읽 었 습 니 다.만약 에 sdcard 에서 읽 지 않 았 다 면 없 었 다 면 네트워크 에서 읽 었 습 니 다.AsynTask 를 사용 하지 않 았 습 니 다.구체 적 인 코드 는 다음 과 같 습 니 다.
/**
* , ImageView
*/
public class ImageDownloader extends AsyncTask<String, Integer, Object> {
private static final String TAG = "ImageDownloader";
// , ( , , ListView )
private Map<String, SoftReference<Drawable>> imageCache = new HashMap<String, SoftReference<Drawable>>();
/**
*
*/
private ImageView mImageView;
public ImageDownloader(ImageView image) {
mImageView = image;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected Object doInBackground(String... params) {
// Log.i("ImageDownloader", "loading image...");
String url = params[0];
Drawable drawable = null;
try {
if (!"".equals(url) && url != null) {
String fileName = url.hashCode()+".jpg";
//
if (imageCache.containsKey(fileName)) {
SoftReference<Drawable> softReference = imageCache.get(fileName);
drawable = softReference.get();
if (drawable != null) {
return drawable;
}
}
File dir = new File(FileConstant.IMAGE_FILE_PATH);
if (!dir.exists()) {
boolean m = dir.mkdirs();
}
File file = new File(dir, fileName);
if (file.exists() && file.length() > 0) {
Log.i(TAG, "load image from sd card");
// sdcard
drawable = readFromSdcard(file);
} else {
//file.createNewFile();
Log.i(TAG, "load image from network");
URL imageUrl = new URL(url);
// sdcard
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
saveImageFile(imageUrl, file);
drawable = Drawable.createFromStream(new FileInputStream(file), fileName);
}else{
//
drawable = Drawable.createFromStream(imageUrl.openStream(), fileName);
}
}
if(drawable!=null){
//
imageCache.put(fileName, new SoftReference<Drawable>(drawable));
}
}
} catch (Exception e) {
e.printStackTrace();
}
return drawable;
}
/**
* save image
*/
private void saveImageFile(URL url, File file) {
FileOutputStream out = null;
InputStream in = null;
try {
file.deleteOnExit();
out = new FileOutputStream(file);
in = url.openStream();
byte[] buf = new byte[1024];
int len = -1;
while((len = in.read(buf))!=-1){
out.write(buf, 0, len);
out.flush();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if(out!=null){
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(in!=null){
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* sdcard
*/
private Drawable readFromSdcard(File file) throws Exception {
FileInputStream in = new FileInputStream(file);
return Drawable.createFromStream(in, file.getName());
}
@Override
protected void onPostExecute(Object result) {
super.onPostExecute(result);
Drawable drawable = (Drawable) result;
if (mImageView != null && drawable != null) {
mImageView.setBackgroundDrawable(drawable);
}
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
}
@Override
protected void onCancelled() {
super.onCancelled();
}
}
이 Image Downloader 2 의 사용 도 간단 합 니 다.
public class ImageUtil {
/**
* image loader
*/
static ImageDownloader2 loader = null;
/**
* load image
*/
public static void loadImage(String url,final ImageView imageView){
if(loader == null){
loader = new ImageDownloader2();
}
loader.loadDrawable(url, new ImageCallback() {
@Override
public void imageLoaded(Drawable imageDrawable) {
if(imageDrawable!=null){
imageView.setBackgroundDrawable(imageDrawable);
}
}
});
}
}
매번 사용 할 때마다 ImageUtil.loadImage(url,imageView)를 호출 하여 그림 url 이 이미 그림 을 표시 해 야 하 는 컨트롤 ImageView 의 인용 을 전송 하면 됩 니 다.이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Bitrise에서 배포 어플리케이션 설정 테스트하기이 글은 Bitrise 광고 달력의 23일째 글입니다. 자체 또는 당사 등에서 Bitrise 구축 서비스를 사용합니다. 그나저나 며칠 전 Bitrise User Group Meetup #3에서 아래 슬라이드를 발표했...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.