使用AysnTask进行图片的异步缓存


在现在的app开发中,为了提高用户的体验效果,通常会对部分进入的主页面进行页面数据的缓存,一般的操作将服务器返回的首页的json字符串进行保存,也就是保留了文字部分,下面就是保存json字符串的部分,将数据的文字部分进行保存,图片值保存了URL路径

public class UtilsSaveCache {


    private static UtilsSaveCache mInstance;

//    private static Context mContext;

    private UtilsSaveCache() {
//        this.mContext = context;
    }

    public synchronized static UtilsSaveCache getInstance() {
        if (mInstance == null) {
            mInstance = new UtilsSaveCache();
        }
        return mInstance;
    }


    public void saveCache(String json, String fileName) {
        //会导致崩溃的:bitmapsqlite        BufferedWriter writer = null;
        try {
            writer = new BufferedWriter(new FileWriter(getCacheFile(fileName)));
            writer.write(System.currentTimeMillis() + "");
            writer.newLine();
            writer.write(json); //写单行的json
            writer.flush();
            LogUtils.e("json 缓存保存成功");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (writer != null) {
                try {
                    writer.close();
                    writer = null;
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }


    public File getCacheFile(String fileName) {
        LogUtils.e(fileName);
        File dir = null;
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            dir = new File(Environment.getExternalStorageDirectory(),
                    "Android/data/" + AppManager.getInstance().getPackageName() + "/Cache");
        } else {
            dir = new File(AppManager.getInstance().getPackageName(), "Cache");
        }
        if (!dir.exists()) {
            dir.mkdirs();
        }
        String md5Str = Md5Util.getMD5Str(fileName);
        File file = new File(dir, md5Str);
        return file;
    }

获取本地缓存的json字符串如下UtilsSaceCache中getLocalData方法
方法

public String getLocalData(String fileName) {
    File file = getCacheFile((fileName));
    BufferedReader reader = null;
    try {
        reader = new BufferedReader(new FileReader(file));
        String oldtime = reader.readLine();
        if (Long.parseLong(oldtime) + AppConfig.CACHE_SAVE_TIME < System.currentTimeMillis()) {
            Log.e("json", " json 缓存过期啦");
            return null;
        }
        String json = reader.readLine(); //要求保存json就保存单行
        if (TextUtils.isEmpty(json)) {
            Log.e("json", " json 缓存位空");
            return null;
        } else {
            Log.e("json", " json 缓存拿到了啦");
            return json;
        }

    } catch (Exception e) {
        e.printStackTrace();
        return null;
    } finally {
        if (reader != null) {
            try {
                reader.close();
                reader = null;
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }
}

保存数据的时候调用

UtilsSaveCache.getInstance().saveCache(bean.response, 文件名字);

读取的时候调用

String localData = UtilsSaveCache.getInstance().getLocalData(文件名字);



到此,已经有一个完成的工具类保存jsonString的字符串了,但是,图片值保存了URL路径,在没有网络的时候也加载不出来呀?

这里就要使用到异步加载AysnTask了,这个是根据URL路径保存图片的异步加载


/**
 * Created by huguomin on 2017/4/7.
 */

public class ImageCacheImageAsynTask extends AsyncTask<String, Void, Bitmap> {
    URL url = null;

    public ImageCacheImageAsynTask() {
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }

    @Override
    protected Bitmap doInBackground(String... params) {
        //根据url路径,将图片保存到本地
        InputStream inputStream = null;
        HttpURLConnection urlConnection = null;
        Bitmap bmp = null;
        try {
            url = new URL(params[0]);
            urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.setRequestMethod("GET");
            urlConnection.setConnectTimeout(10000);
            inputStream = urlConnection.getInputStream();
            byte[] bt = getBytesFromStream(inputStream);
            LogUtils.e("bitmapCahche--->转换成bitmap对象------");
            bmp = BitmapFactory.decodeByteArray(bt, 0, bt.length);
        } catch (MalformedURLException e) {
            e.printStackTrace();
            return null;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        } finally {
            if (null != inputStream) {
                try {
                    inputStream.close();
                    inputStream = null;
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != urlConnection) {
                urlConnection.disconnect();
                urlConnection = null;
            }
        }
        //将图片保存到本地
        saveMyBitmap((url.toString()), bmp);
        return bmp;
    }

    @Override
    protected void onPostExecute(Bitmap bitmap) {
        //将图片保存到本地
//       saveMyBitmap((url.toString()), bitmap);
    }

    private byte[] getBytesFromStream(InputStream inputStream) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] buf = new byte[1024 * 10];
        int len = 0;
        while (len != -1) {
            try {
                len = inputStream.read(buf);
                if (len != -1) {
                    baos.write(buf, 0, len);
                    //    baos.flush();
                  //  LogUtils.e("bitmapCahche*-*-*-正在写入图片------" + buf.length);
                }
            } catch (IOException e) {
                e.printStackTrace();
                LogUtils.e("bitmapCahche*-*-*-写入出错------" + e.toString());
                len = -1;
            }
        }
        if (inputStream != null) {
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        LogUtils.e("bitmapCahche*-*-*-图片写入完毕------");
        return baos.toByteArray();
    }


    public void saveMyBitmap(String bitName, Bitmap mBitmap) {
        System.out.println("" + "保存数据到本地" + "mingzi = " + bitName);
        File cacheFile = UtilsSaveCache.getInstance().getPicCacheFile(bitName);
        //保存一下路径,方便服务器上传的时候用
        FileOutputStream fOut = null;
        try {
            fOut = new FileOutputStream(cacheFile);
            mBitmap.compress(Bitmap.CompressFormat.PNG, 100, fOut);//Bitmap对象解析成流
            //保存成功,存一个标记
            LogUtils.e("*-*-*-保存陈宫" + cacheFile.getAbsolutePath());
        } catch (Exception e) {
            e.printStackTrace();
            //保存失败的失败的时候删除文件
            if (cacheFile.exists())cacheFile.delete();
            LogUtils.e("*-*-*-保存失败" + e.toString() );
        } finally {
            try {
                if (fOut != null) {
                    fOut.flush();
                    fOut.close();
                    fOut = null;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}


getPicCacheFile是saveCache工具类中的

public File getPicCacheFile(String fileName) {
    LogUtils.e(fileName);
    File dir = null;
    if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
        dir = new File(Environment.getExternalStorageDirectory(),
                "Android/data/" + AppManager.getInstance().getPackageName() + "/Pic_Cache");
    } else {
        dir = new File(AppManager.getInstance().getPackageName(), "Pic_Cache");
    }
    if (!dir.exists()) {
        dir.mkdirs();
    }
    String md5Str = Md5Util.getMD5Str(fileName);
    File file = new File(dir, md5Str+".png");
    return file;
}


异步怎么获取图片呢?我使用Fresco进行图片加载的,异步加载如下,这个是一种方法,异步进行架子啊,将ImagView的对象通过构造方法传入,onPostExecute进行加载

 imageview.setImageBitmap(bitmap);


/**
 * Created by huguomin on 2017/4/15.
 */

public class AsynTaskLoadLocalBitmap extends AsyncTask<String,Void,Bitmap> {

    private SimpleDraweeView imageview;
    public ArrayList<Bitmap> bitmaps = new ArrayList<>();

    public AsynTaskLoadLocalBitmap(SimpleDraweeView view){
        this.imageview= view;
    }
    public Bitmap mBitmap ;


    @Override
    protected Bitmap doInBackground(String... params) {
        //读取本地文件
        File cacheFile = UtilsSaveCache.getInstance().getCacheFile(params[0]);
        FileInputStream fis = null;
        Bitmap bitmap = null;
        try {
            fis = new FileInputStream(cacheFile.getAbsoluteFile());
              bitmap  = BitmapFactory.decodeStream(fis);
            LogUtils.e("AsynTaskLoadLocalBitmap 正在本地图片--" + cacheFile.getAbsolutePath());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return null;
        }
        return bitmap;
    }

    @Override
    protected void onPostExecute(Bitmap bitmap) {
            imageview.setImageBitmap(bitmap);
         
    }
}


当然,你也可以加载本地的文件,使用方法如下:

if (!NetUtils.isConnected(mContext) && UtilsSaveCache.getInstance().localFileExitence(item.getTitle_picture()) ){
    String absolutePath = UtilsSaveCache.getInstance().getPicCacheFile(item.getTitle_picture()).getAbsolutePath();
    Uri uri = Uri.fromFile(new File(absolutePath));
    image.setImageURI(uri);

}else{
    if (item.getTitle_picture() != null){
        Uri uri = Uri.parse(item.getTitle_picture());
        image.setImageURI(uri);
        if (!SharedPrefsUtils.getBoolean(AppConfig.IS_FIRST_ENTER)&&NetUtils.isConnected(mContext)&& !UtilsSaveCache.getInstance().localFileExitence(item.getTitle_picture())){
            new ImageCacheImageAsynTask().execute(item.getTitle_picture());
            
        }
    }
}


当然,判断当地文件是否存在

UtilsSaveCache.getInstance().localFileExitence(item.getTitle_picture())

public boolean localFileExitence(String fileName){
    File file = getPicCacheFile((fileName));
    if (file.exists()){
        return true;
    }
    return false;
}


一个完整的异步加载图片就达成了,在没有网络的时候,用户进去也能看到部分保存的数据,谢谢




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值