在现在的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) { //会导致崩溃的:bitmap、sqlite的 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; }
一个完整的异步加载图片就达成了,在没有网络的时候,用户进去也能看到部分保存的数据,谢谢