안드로이드 그림을 비동기적으로 불러오는 실현

6497 단어
android 응용 프로그램은 여러 개의 그림을 불러오는 것을 자주 볼 수 있습니다.
내가 그림을 써서 불러오는 사고방식은 먼저 메모리에 있는지 없는지를 보고 로컬에서 있는지 없는지를 보지 않으면 마지막으로 인터넷에서 다운로드하는 것이다.
코드를 넣고 벽돌을 던져 옥을 끌어들이다.

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.graphics.drawable.BitmapDrawable;

import android.graphics.drawable.Drawable;

import android.os.Environment;

import android.os.Handler;

import android.os.Message;

import android.support.annotation.Nullable;

import android.util.Base64;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.lang.ref.SoftReference;

import java.net.MalformedURLException;

import java.net.URL;

import java.util.HashMap;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

/**

*        

* 2018-04-06

* StoneFu

*/

public class AsyncImageLoader {

private static final StringTAG="AsyncImageLoader";

    private static final StringDIR=".www.cctv.com";

    private static final int MSG_MEMORY=0;

    private static final int MSG_SDCARD=1;

    private static final int MSG_NET=2;

    private HashMap>imageCache;

    private ExecutorServicemExecutorService;

    private static AsyncImageLoadersAsyncImageLoader;

    private  AsyncImageLoader() {

imageCache =new HashMap<>();

        int i=Runtime.getRuntime().availableProcessors()/2+1;

        JLog.e(TAG+",AsyncImageLoader-->i:"+i);

        mExecutorService = Executors.newFixedThreadPool(i);

    }

public static AsyncImageLoadergetInstance(){

if(sAsyncImageLoader==null){

sAsyncImageLoader=new AsyncImageLoader();

        }

return sAsyncImageLoader;

    }

private StringgetFileName(String url){

String encodedString = Base64.encodeToString(url.getBytes(), Base64.DEFAULT);

        String name=""+encodedString+".jpg";

        return name;

    }

private DrawableloadDrawableFromSDCard(String url){

String name=getFileName(url);

        try{

File file=getFile(name);

            FileInputStream fis =new FileInputStream(file);

            Bitmap bitmap  = BitmapFactory.decodeStream(fis);

            if(bitmap!=null){

Drawable drawable=new BitmapDrawable(bitmap);

                return drawable;

            }

}catch (IOException e){

e.printStackTrace();

        }

return null;

    }

public void loadDrawable(final String imageUrl, final ImageCallback imageCallback) {

final  Handler handler =new Handler() {

public void handleMessage(@Nullable Message message) {

JLog.e("---------------------->msg.what:"+message.what);

                    imageCallback.imageLoaded((Drawable) message.obj, imageUrl);

                }

};

        //memory

        if (imageCache.containsKey(imageUrl)) {

SoftReference softReference =imageCache.get(imageUrl);

            Drawable drawable = softReference.get();

            if (drawable !=null) {

Message message = handler.obtainMessage(MSG_MEMORY, drawable);

                handler.sendMessage(message);

            }

}

//sdcard

        Drawable drawable=loadDrawableFromSDCard(imageUrl);

        if(drawable!=null){

imageCache.put(imageUrl, new SoftReference<>(drawable));

            Message message = handler.obtainMessage(MSG_SDCARD, drawable);

            handler.sendMessage(message);

return ;

        }

//net

        mExecutorService.execute(new Runnable() {

@Override

            public void run() {

Drawable drawable =loadImageFromUrl(imageUrl);

                if(drawable!=null){

Bitmap bmp=((BitmapDrawable)drawable).getBitmap();

                    saveBitmapToSDCard(bmp,getFileName(imageUrl),Bitmap.CompressFormat.JPEG);

                }

imageCache.put(imageUrl, new SoftReference(drawable));

                Message message =handler.obtainMessage(MSG_NET, drawable);

                handler.sendMessage(message);

            }

});

    }

private static DrawableloadImageFromUrl(String strUrl) {

URL url;

        InputStream i =null;

        try {

url =new URL(strUrl);

            i = (InputStream) url.getContent();

        }catch (MalformedURLException e1) {

e1.printStackTrace();

        }catch (IOException e) {

e.printStackTrace();

        }

Drawable d = Drawable.createFromStream(i, "src");

        return d;

    }

private FilegetFile(String name){

File appDir=new File(Environment.getExternalStorageDirectory(),DIR);

        if(!appDir.exists())

appDir.mkdir();

        File file=new File(appDir,name);

        return file;

    }

private  boolean saveBitmapToSDCard(Bitmap bitmap, String name, Bitmap.CompressFormat format){

JLog.e(TAG+",saveBitmapToSDCard");

        boolean isRet=true;

        FileOutputStream out;

        File file=getFile(name);

        try{

out=new FileOutputStream(file);

            bitmap.compress(format,100,out);

            out.flush();

            out.close();

        }catch (IOException e){

e.printStackTrace();

            isRet=false;

        }

return  isRet;

    }

public interface ImageCallback {

void imageLoaded(Drawable imageDrawable, String imageUrl);

    }

}

2018년 4월 24일 업데이트
이 글은http://dev.bizo.com/2014/06/cached-thread-pool-considered-harmlful.html) Executors를 직접 사용하는 방법에 대해 설명합니다.newCachedThreadPool()이 최적이 아닙니다.주로 다음과 같은 두 가지 이유가 있다.
1, FixedTheadPool 및 SignalThreadPool: 허용된 요청 열 쌍의 길이는 Integer입니다.MAX_VALUE, 많은 요청이 쌓여서 OOM이 될 수 있습니다.
2. CachedThreadPool과 ScheduledThreadPool: 스레드 데이터를 Integer로 만들 수 있습니다.MAX_VALUE 는 대량의 스레드를 생성하여 OOM을 만들 수 있습니다.
이러한 이유로 ExecutorService는 다음과 같이 인스턴스화됩니다.
private static final int KEEP_ALIVE_TIME=30;

private static final TimeUnitKEEP_ALIVE_TIME_UNIT=TimeUnit.SECONDS;

private BlockingQueueblockingQueue=new LinkedBlockingDeque();

private void initExecutorService(){

int i=Runtime.getRuntime().availableProcessors();

//JLog.e(TAG+",AsyncImageLoader-->i:"+i);

//mExecutorService = Executors.newFixedThreadPool(i);

mExecutorService=new ThreadPoolExecutor(i, i *2, KEEP_ALIVE_TIME, KEEP_ALIVE_TIME_UNIT, blockingQueue, new ThreadFactory() {

@Override

    public ThreadnewThread(@NonNull Runnable r) {

return null;

    }

}, new RejectedExecutionHandler() {

@Override

    public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {

}

});

}

페이스북 소스 이미지 로드 라이브러리
https://www.fresco-cn.org/docs/index.html

좋은 웹페이지 즐겨찾기