Android简单实现 缓存数据

前言

1、每一种要缓存的数据都是有对应的versionCode,通过versionCode请求网络获取是否需要更新

2、提前将要缓存的数据放入assets文件夹中,打包上线。

缓存设计

代码实现

/**
 * Created by huangbo on 2017/6/19.
 *
 * 主要是缓存的工具类
 *
 * 缓存设计:
 *         0.从内存中读取数据 :0.1 读取成功-> 取出versionCode ->3
 *                             0.2 读取失败-> 1
 *
 *         1.从文件中读取数据:1.1读取成成功-> 取出versionCode ->3
 *                             1.2读取失败-> 2
 *         2.从Assets中读取数据:2.1读取成功-> 取出versionCode ->3
 *                                2.2读取失败-> versionCode==0 ->3
 *
 *         3.用versionCode请求网络 3.1请求成功(有版本更新)将文件写入内存,写入文件;
 *                                 3.1 请求失败,(没有版本更新)
 *
 */

public class CacheData {

    public static CacheData cacheData;

    public static CacheData getInstance() {
        if (cacheData == null) {
            cacheData = new CacheData();
        }
        return cacheData;
    }

    String mFileName;

    public CacheData cacheName(String mFileName) {
        this.mFileName = mFileName;
        return this;
    }

    ExecutorService cachedThreadPool;

    private CacheData() {
        cachedThreadPool = Executors.newCachedThreadPool();
    }

    /**
     * 从assets 中读取文件
     *
     * @return cacheData 的Json串
     */
    private String readDataFromAssets() {
        try {
            InputStream ips = AppUtils.ApplicationContext.getAssets().open(mFileName);
            byte[] bytes = new byte[ips.available()];
            ips.read(bytes);
            ips.close();
            return new String(bytes);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "";
    }

    public void readDataFromAssets(final Handler handler) {
        cachedThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                String json = readDataFromAssets();
                Message message = handler.obtainMessage(1, json);
                handler.sendMessage(message);
            }
        });
    }
    public void readDataFromFile(final Handler handler) {
        cachedThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                Message message = handler.obtainMessage(1, readDataFromFile());
                handler.sendMessage(message);
            }
        });

    }

    /**
     * 将region 更新到指定文件里
     * @param
     */

    public void writeData2FileWithThread(final String Data) {
        cachedThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                writeRegion2File(Data);
            }
        });
    }

    /**
     * @return cacheData 的Json串
     */

    private String readDataFromFile() {
        try {
            File file = new File(AppUtils.getCacheDirectory(), mFileName);
            if (!file.exists()) {
                return null;
            }
            FileInputStream fis = new FileInputStream(file);
            byte[] bytes = new byte[fis.available()];
            fis.read(bytes);
            fis.close();
            return new String(bytes);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "";

    }

    private void writeData2File(String jsonData) {
        try {
            File cityFile = new File(AppUtils.getCacheDirectory(), mFileName);
            if (!cityFile.exists()) {
                cityFile.createNewFile();
            }
            FileOutputStream fos = new FileOutputStream(cityFile);
            fos.write(regionJsonData.getBytes("UTF-8"));
            fos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

使用方法

/**
 * Created by huangbo on 2017/6/8.
 */

public class Region {
    public static Region region;

    public static Region getInstance() {
        if (region == null) {
            region = new Region();
        }
        return region;
    }

    ProvinceCityBean provinceCityBean;

    public int getVersion() {
        return provinceCityBean == null ? 0 : provinceCityBean.getVersion();
    }

    public ProvinceCityBean getProvinceCityBean() {
        return provinceCityBean;
    }

    public void setProvinceCityBean(final String mRegionJson, final Handler handler) {
        if (TextUtils.isEmpty(mRegionJson)) {
            return;
        }
        cachedThreadPool.execute(new Runnable() {
            @Override
            public void run() {
                provinceCityBean = GsonUtils.GsonToBean(mRegionJson, ProvinceCityBean.class);
                if (handler != null) {
                    handler.sendEmptyMessage(1);
                }
            }
        });
    }
    ExecutorService cachedThreadPool;
    CacheData cacheData;

    private Region() {
        cachedThreadPool = Executors.newCachedThreadPool();
        cacheData = CacheData.getInstance().cacheName(Const.REGION_JSON);
    }

    /**
     * 具体调用方法
     */
    public void cacheRegion() {
        if (provinceCityBean == null) {
            readRegionFromFile();
        } else {
            readRegionFromHttp();
        }
    }

    private void readRegionFromFile() {
        cacheData.readDataFromFile(new Handler() {
            @Override
            public void handleMessage(Message msg) {
                String jsonRegion = (String) msg.obj;
                onReadRegionFromFileBack(jsonRegion);
            }
        });
    }

    /**
     * 从文件中读取数据,若为null 继续从Asset中获取
     *
     * @param jsonRegion
     */
    private void onReadRegionFromFileBack(String jsonRegion) {
        if (!TextUtils.isEmpty(jsonRegion)) {/*文件中读取成功 设置到Region中更新json 取出version请求网络判断是否为最新的版本 */
            setProvinceCityBean(jsonRegion, httpHandler);
        } else {/*文件中读取失败  从assets 中继续读取*/
            cacheData.readDataFromAssets(new Handler() {
                @Override
                public void handleMessage(Message msg) {
                    String jsonRegion = (String) msg.obj;
                    onReadRegionFromAssetsBack(jsonRegion);
                }
            });
        }
    }

    private void onReadRegionFromAssetsBack(String jsonRegion) {
        if (!TextUtils.isEmpty(jsonRegion)) {/*从assets中读取成功 设置到Region中更新json*/
            setProvinceCityBean(jsonRegion, httpHandler);
        } else {
            readRegionFromHttp();
        }
    }

    private void readRegionFromHttp() {
        ReqRegion reqRegion = new ReqRegion();
        reqRegion.sendRequest(false, new OnHttpResult() {
            @Override
            public void onHttpSuccess(String data) {
                setProvinceCityBean(data, null);
                cacheData.writeData2FileWithThread(data);
            }
            @Override
            public void onHttpFailure(String message) {

            }
        });
    }

    Handler httpHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            readRegionFromHttp();
        }
    };
}
Region.getInstance().cacheRegion();//实现缓存

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。如有错误或未考虑完全的地方,望不吝赐教。

(0)

相关推荐

  • Android中如何加载数据缓存

    最近app快完工了,但是很多列表加载,新闻咨询等数据一直从网络请求,速度很慢,影响用户体验,所以寻思用缓存来加载一些更新要求不太高的数据 首先做一个保存缓存的工具类 import java.io.File; import java.io.IOException; import android.content.Context; import android.os.Environment; import android.util.Log; /** * 缓存工具类 */ public class Co

  • 浅谈Android轻量级的数据缓存框架RxCache

    请求网络数据是在安卓开发中使用最频繁的一个功能,网络请求的体验决定了用户对整个APP的感觉,因此合理地使用缓存对网络请求的数据进行处理极为重要.合理的进行缓存和网络请求,可以为APP带来更优秀的体验.图片的缓存有Picasso.Glide.Fresco等非常著名的框架,它们极为成熟并且使用广泛,程序员应该做的是使用轮子而非重复造轮子.但对于网络数据的缓存,大多都是自用自封装,每个人都需要进行繁琐的编码工作.RxCache就对网络缓存进行了封装,并采用RxJava模式,可以与其他RxJava的代码

  • android开发教程之清除android数据缓存示例(清除本地数据缓存)

    复制代码 代码如下: /*  * 文 件 名:  DataCleanManager.java  * 描    述:  主要功能有清除内/外缓存,清除数据库,清除sharedPreference,清除files和清除自定义目录  */ import java.io.File;import android.content.Context;import android.os.Environment; /** * 本应用数据清除管理器 */public class DataCleanManager { 

  • android实现缓存图片等数据

    采用LinkedHashMap自带的LRU 算法缓存数据, 可检测对象是否已被虚拟机回收,并且重新计算当前缓存大小,清除缓存中无用的键值对象(即已经被虚拟机回收但未从缓存清除的数据):  * 默认内存缓存大小为: 4 * 1024 * 1024 可通过通过setMaxCacheSize重新设置缓存大小,可手动清空内存缓存  * <br>支持内存缓存和磁盘缓存方式, 通过 {@link cc.util.cache.NetByteWrapper} 支持HTTP缓存 (注:详细参考cc.util.h

  • Android简单实现 缓存数据

    前言 1.每一种要缓存的数据都是有对应的versionCode,通过versionCode请求网络获取是否需要更新 2.提前将要缓存的数据放入assets文件夹中,打包上线. 缓存设计 代码实现 /** * Created by huangbo on 2017/6/19. * * 主要是缓存的工具类 * * 缓存设计: * 0.从内存中读取数据 :0.1 读取成功-> 取出versionCode ->3 * 0.2 读取失败-> 1 * * 1.从文件中读取数据:1.1读取成成功->

  • Android图片三级缓存策略(网络、本地、内存缓存)

    一.简介 现在的Android应用程序中,不可避免的都会使用到图片,如果每次加载图片的时候都要从网络重新拉取,这样不但很耗费用户的流量,而且图片加载的也会很慢,用户体验很不好.所以一个应用的图片缓存策略是很重要的.通常情况下,Android应用程序中图片的缓存策略采用"内存-本地-网络"三级缓存策略,首先应用程序访问网络拉取图片,分别将加载的图片保存在本地SD卡中和内存中,当程序再一次需要加载图片的时候,先判断内存中是否有缓存,有则直接从内存中拉取,否则查看本地SD卡中是否有缓存,SD

  • Android 简单的图片查看器源码实现

    本文介绍了Android 简单的图片查看器源码实现,分享给大家,具体如下: public class MainActivity extends Activity { private EditText et_path; private ImageView iv; //创建handler 对象 // private Handler handler = new Handler(){ // // //处理消息 // public void handleMessage(android.os.Message

  • Android简单实现无限滚动自动滚动的ViewPager

    经常我们会在应用中看到一个可以自动滚动,并且无限滚动的一个ViewPager,百度谷歌上面也有很多关于这方面的教程,但是感觉都略显麻烦,而且封装的都不是很彻底.所以试着封装一个比较好用的ViewPager 效果如下: 简单的说一下实现思路,要实现无限滚动的话就要在PagerAdapter上面做一些手脚,在PagerAdapter的getCount的函数的返回值设置成Integer.MXA_VALUE就可以实现向右无限滚动,但是要实现向左无限滚动呢?就是一开始的时候setCurrentItem的时

  • Webview实现android简单的浏览器实例代码

    WebView是Android中一个非常实用的组件,它和Safai.Chrome一样都是基于Webkit网页渲染引擎,可以通过加载HTML数据的方式便捷地展现软件的界面,下面通过本文给大家介绍Webview实现android简单的浏览器实例代码. 实现了浏览器的返回 前进 主页 退出 输入网址的功能 注释的很清楚啦 就不多说了 首先是布局文件 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android&qu

  • 在android中使用缓存和脱机存储

    目录 1.在android中使用缓存和脱机存储 2.Offline storage离线存储 1.在android中使用缓存和脱机存储 缓存可以加速你的应用程序,即使在网络不可用时,用户能够更加流畅地使用你的应用程序使用缓存是相当简单的,需要一个单一的代码行. 导入 import com.shephertz.app42.paas.sdk.android.App42CacheManager即可,同时需要设置缓存策略.  Policy.CACHE_FIRSTSetting 将激活所有数据的读操作首先从

  • Android实现从缓存中读取图片与异步加载功能类

    本文实例讲述了Android实现从缓存中读取图片与异步加载功能类.分享给大家供大家参考,具体如下: 在新浪微博的微博列表中的图片,为了加速其显示也为了加快程序的响应,可以参考该图片异步加载类实现. public class AsyncImageLoader { //SoftReference是软引用,是为了更好的为了系统回收变量 private HashMap<String, SoftReference<Drawable>> imageCache; public AsyncImag

  • Android简单实现启动画面的方法

    本文实例讲述了Android简单实现启动画面的方法.分享给大家供大家参考,具体如下: 核心代码: package com.demo.app; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.os.Handler; public class SplashActivity extends Activity { private final int S

  • Android简单判断某个APK是否已经安装的方法

    本文实例讲述了Android简单判断某个APK是否已经安装的方法.分享给大家供大家参考,具体如下: privateboolean isAppInstalled(String uri){ PackageManager pm = getPackageManager(); boolean installed =false; try{ pm.getPackageInfo(uri,PackageManager.GET_ACTIVITIES); installed =true; }catch(Package

  • Android简单获取经纬度的方法

    本文实例讲述了Android简单获取经纬度的方法.分享给大家供大家参考,具体如下: public void getLoc() { // 位置 LocationManager locationManager; LocationListener locationListener; Location location; String contextService = Context.LOCATION_SERVICE; String provider; double lat; double lon; l

随机推荐