很多时候 我们的应用都要从网络获取数据,不可能每次打开它的时候,都去请求网络获取数据,这样很耗费流量。一个解决的办法是将获取的数据缓存起来,缓存到本地,下次打开应用时,先从缓存里读取数据,如果为空再网络上请求。
效果图:
很明显可以看到: 当我第一次进入应用时【没有缓存】,应用会去从网络加载。当我第二次进入时,因为第一次已经将获取的到数据缓存到了本地,所以就没有从网络获取而是直接显示的,这样就极大的减少流量的使用。
实现思路:
进入应用时,先在本地cache里面读取,如果能读到缓存,就直接将缓存的List数据绑定recylerview进行显示,否则就去从网络请求并显示,然后将这次请求到的数据进行缓存起来。
先把缓存的方法给出来,其实就是序列化对象到本地:
缓存数据
public static <T> void setData(Context context, List<T> list,int type,String tag)
{
File file = context.getCacheDir();
File Cache = null;
String name;
if(type==0){
name = Cache_Movie + tag;
Cache = new File(file,name);
}else if(type==1){
name = Cache_Book + tag;
Cache = new File(file,name);
}else {
name = Cache_Top_Movie_ + tag;
Cache = new File(file,name);
}
if(Cache.exists()){
Cache.delete();
}
try {
ObjectOutputStream outputStream =
new ObjectOutputStream(new FileOutputStream(Cache));
outputStream.writeObject(list);
} catch (IOException e) {
e.printStackTrace();
}
}
读取数据:
public static <T> List<T> getData(Context context,String tag, int type) throws IllegalAccessException, InstantiationException {
File file = context.getCacheDir();
String name;
File cache;
List<T> list = null;
if(type==0){
name = Cache_Movie + tag;
cache = new File(file,name);
if(!cache.exists()){
return null;
}
try {
ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream(cache));
list = (List<T>) inputStream.readObject();
return list;
} catch (Exception e) {
e.printStackTrace();
}
}else if(type==1){
name = Cache_Book + tag;
cache = new File(file,name);
if(!cache.exists()){
return null;
}
try {
ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream(cache));
list = (List<T>) inputStream.readObject();
return list;
} catch (Exception e) {
e.printStackTrace();
}
}else {
name = Cache_Top_Movie_ + tag;
cache = new File(file,name);
if(!cache.exists()){
return null;
}
try {
ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream(cache));
list = (List<T>) inputStream.readObject();
return list;
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
}
然后是进入应用时,进行读取
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
adapter = new TypeAdapter();
List<MovieInfo> cache = null;
try {
cache = SaveData.getData(getActivity(),movieTAg,0); //获取缓存数据
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (java.lang.InstantiationException e) {
e.printStackTrace();
}
if(cache!=null){ //不为空,即缓存中有数据
Log.i(TAG,"cache is not null");
mMovieInfos = cache;
mCurrentStart = mMovieInfos.size()/20-1;
}else{ //为空,从网络获取
AsyncTask<String, Integer, List<MovieInfo>> task = new AsyncTask<String, Integer, List<MovieInfo>>() {
@Override
protected List<MovieInfo> doInBackground(String... strings) {
Log.i(TAG,"doInback movietag is: " + movieTAg);
return new FetchMovies().getMoviesByTag(movieTAg, mCurrentStart);
}
@Override
protected void onPostExecute(List<MovieInfo> movieInfos) {
super.onPostExecute(movieInfos);
mMovieInfos = movieInfos;
SaveData.setData(getActivity(),movieInfos,0,movieTAg); //将获取到的数据缓存起来
adapter.notifyDataSetChanged();
}
};
task.execute();
}
setRetainInstance(true);
}
可以看到:
在onCreate那里,我显示从缓存读取数据,如果读到了,将list与Adapter绑定起来,进行显示;否则获取从网络数据并将获取的数据缓存起来!