手写简单的图片加载框架

今天翻看旧文件的时候不经意间看到了以前写的图片加载文件,所以拿出来重新理一理。

思路:请求图片优先级:内存缓存》本地缓存》网络

给imageView设置图片的方法:

根据图片请求优先级来,

 /**
     *
     * @param imageView 设置图片的控件
     * @param context 上下文
     * @param url 图片资源路径
     */
    public static void setBitmapFromCache(ImageView imageView,Context context,String url){
        if(TextUtils.isEmpty(url)){
            return;
        }
        Bitmap bitmap=null;
        //先从内存缓存中查找图片资源
        bitmap=getBitmapFromMemoryCache(url);
        if(bitmap!=null){
            imageView.setImageBitmap(bitmap);
            return;
        }
        //再从应用的缓存目录中查找图片
        bitmap=getBitmapFormFileCache(context,url);
        if(bitmap!=null){
            imageView.setImageBitmap(bitmap);
            return;
        }
        //再从网络上去异步请求
        getBitmapAsyncLoad(imageView,url,context);
    }


然后分别看一下三个请求方法的具体实现:

1.内存缓存:

//从内存缓存中获取bitmap
    private static Bitmap getBitmapFromMemoryCache(String url) {
        Bitmap bitmap=null;
        if(url!=null){
            bitmap=lruCache.get(url);
        }
        return bitmap;
    }


2.本地缓存:

//从文件缓存(应用的缓存目录)获得数据
    private static Bitmap getBitmapFormFileCache(Context context,String url) {
        Bitmap bitmap=null;
        String fileName= url.substring(url.lastIndexOf("/")+1);//只截取最后一级文件名,如:sdcard/pics/demo.jpg截取后-->>demo.jpg
        //获得应用的缓存目录
        File cacheDir=context.getCacheDir();
        if(cacheDir!=null){
            File[] files=cacheDir.listFiles();
            for(int i=0;i                 if(files[i].getName().equals(fileName)){
                    bitmap=BitmapFactory.decodeFile(files[i].getAbsolutePath());
                    return bitmap;
                }
            }
        }
        return bitmap;
    }


3.从网络请求图片资源,并在请求成功后将bitmap分别存入内存缓存和本地缓存中:

使用基础网络请求框架HttpURLConnection和异步任务AsyncTask实现异步网络请求:

 private static void getBitmapAsyncLoad(ImageView imageView, String url,Context context) {
        MyAsyncTask task=new MyAsyncTask(context, imageView);
        task.execute(url);
    }

    static class  MyAsyncTask extends AsyncTask{
        Context context;
        ImageView imageView=null;
        public MyAsyncTask(Context context,ImageView imageview) {
            this.context=context;
            this.imageView_header=imageview;
        }
        @Override
        protected Bitmap doInBackground(String... params) {
            Bitmap bitmap=null;
            String  path=params[0];
            try {
                URL url=new URL(path);
                HttpURLConnection connection=(HttpURLConnection) url.openConnection();
                connection.setConnectTimeout(5000);
                connection.setRequestMethod("GET");
                connection.setDoInput(true);

                if(connection.getResponseCode()==200){
                    InputStream inputStream= connection.getInputStream();
                    //把返回的图片资源按比例缩放处理
                    bitmap=compressBitmap(inputStream);
                    //存入缓存
                    if(bitmap!=null){
                        //放到内存缓存中
                        lruCache.put(path, bitmap);
                        //放到应用缓存中
                        bitmapCacheFile(bitmap,path,context);
                    }
                }

            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return bitmap;
        }


        @Override
        protected void onPostExecute(Bitmap result) {
            imageView.setImageBitmap(result);
            super.onPostExecute(result);
        }

其中用到的图片压缩方法:

private Bitmap  compressBitmap(InputStream inputStream) {
            byte[] datas=getBytesFromStream(inputStream);
            BitmapFactory.Options options=new BitmapFactory.Options();
            //对二进制数据解码时仅做图片的边界处理
            options.inJustDecodeBounds=true;

            BitmapFactory.decodeByteArray(datas, 0, datas.length, options);
            //边界的宽高
            int outWidth=options.outWidth;
            int outHeight=options.outHeight;

            int targetWidth=70;
            int targetHeight=70;

            int wbl=outWidth/targetWidth;
            int hbl=outHeight/targetHeight;

            int bl=wbl>hbl?wbl:hbl;
            if(bl<0){
                bl=1;
            }
            options.inSampleSize=bl;
            options.inJustDecodeBounds=false;

            Bitmap bitmap=BitmapFactory.decodeByteArray(datas, 0, datas.length, options);
            return bitmap;
        }

//从输入流提取字节数组

private static  byte[] getBytesFromStream(InputStream inputStream){
        byte[] datas=null;
        try{
        ByteArrayOutputStream outputStream=new ByteArrayOutputStream();
        
        byte[] buffer=new byte[1024];
        int len=0;
        while((len=inputStream.read(buffer))!=-1){
            outputStream.write(buffer, 0, len);
        }
        datas=outputStream.toByteArray();
        outputStream.close();
        }catch(Exception ex){
            ex.printStackTrace();
        }
        return datas;
    }

网络请求成功后将bitmap存入本地的方法:

private void bitmapCacheFile(Bitmap bitmap, String path,Context context) throws FileNotFoundException {
            File cacheFile=context.getCacheDir();
            if(!cacheFile.exists()){
                cacheFile.mkdirs();
            }
            String fileName=path.substring(path.lastIndexOf("/")+1);
            File file=new File(cacheFile,fileName);
            OutputStream stream=new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
        }


最后别忘了加上内存缓存设置:
    static LruCache lruCache=null;
    static{
        int maxsize=4*1024*1024;
        lruCache=new LruCache(maxsize){
            @Override
            protected int sizeOf(String key, Bitmap value) {
                return value.getRowBytes()*value.getHeight();
            }
        };
    }

你可能感兴趣的:(手写图片请求框架)