几种缓存方案的实现
来源:互联网 发布:mac搜索快捷键是什么 编辑:程序博客网 时间:2024/06/12 20:08
越深入学习,越明白缓存的重要性,例举我认为的需要缓存的场景:
- 从网络上获取的数据不会马上更新的情况,比如 快递信息就不会立马更新,这时候就可以使用缓存机制将获取到的数据缓存到内存,有网络情况下下拉刷新,无网络情况下从缓存中获取数据。
- 一些阅读类,新闻类的app,大部分都是图文结合,频繁的去服务器获取信息 图片的显示会很慢,这时候使用缓存机制,将相关信息存在缓存中,当需要加载相关信息时,先从缓存数据中获取,如果有,直接加载,如果没有,再从服务器去获取数据,速度会快很多。
- 如果数据是网络中获取的,如果不做缓存,那么在无网络情况下,进入界面就是空白一片,造成非常不好的体验,所以缓存是非常重要的一件事。
使用ASimpleCache实现一个快递信息的缓存
ASimpleCache下载链接:https://github.com/yangfuhai/ASimpleCache
首先activity的布局:
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/background" tools:context="example.com.huancuntest.MainActivity"> <android.support.v7.widget.RecyclerView android:id="@+id/recycler_view" android:layout_width="match_parent" android:layout_height="match_parent"></android.support.v7.widget.RecyclerView></RelativeLayout>
RecyclerView的item布局:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@android:color/white" android:layout_margin="2dp" > <TextView android:id="@+id/tv_content" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="content" android:textColor="@color/textColor" android:layout_margin="5dp" android:textSize="18sp"/> <TextView android:id="@+id/tv_time" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="time" android:textColor="@color/textColor" android:layout_marginLeft="5dp"/></LinearLayout>
接下来实体类,先看json数组
{
"message": "ok",
"nu": "227873745185",
"ischeck": "1",
"condition": "F00",
"com": "shentong",
"status": "200",
"state": "3",
"data": [
{
"time": "2017-03-19 20:01:33",
"ftime": "2017-03-19 20:01:33",
"context": "[云南丽江公司]小许派,本人签-已签收",
"location": null
},
{
"time": "2017-03-19 10:37:25",
"ftime": "2017-03-19 10:37:25",
"context": "[云南丽江公司]云南丽江公司-南门片区-派件中",
"location": null
},
{
"time": "2017-03-19 09:16:33",
"ftime": "2017-03-19 09:16:33",
"context": "[云南丽江公司]已到达-云南丽江公司",
"location": null
},
{
"time": "2017-03-19 09:16:22",
"ftime": "2017-03-19 09:16:22",
"context": "[云南丽江公司]已到达-云南丽江公司",
"location": null
},
{
"time": "2017-03-18 10:07:16",
"ftime": "2017-03-18 10:07:16",
"context": "[云南昆明航空部]已到达-云南昆明航空部",
"location": null
},
{
"time": "2017-03-18 10:07:12",
"ftime": "2017-03-18 10:07:12",
"context": "[云南昆明航空部]云南昆明航空部-已发往-云南丽江公司",
"location": null
},
{
"time": "2017-03-17 02:03:37",
"ftime": "2017-03-17 02:03:37",
"context": "[广东东莞中转部]广东东莞中转部-已装袋发往-云南昆明航空部",
"location": null
},
{
"time": "2017-03-16 23:14:29",
"ftime": "2017-03-16 23:14:29",
"context": "[广东东莞凤岗分部]广东东莞凤岗分部-已发往-广东东莞中转部",
"location": null
},
{
"time": "2017-03-16 22:08:38",
"ftime": "2017-03-16 22:08:38",
"context": "[广东东莞凤岗分部]广东东莞凤岗分部-刘国贤-已收件",
"location": null
}
]
}
"message": "ok",
"nu": "227873745185",
"ischeck": "1",
"condition": "F00",
"com": "shentong",
"status": "200",
"state": "3",
"data": [
{
"time": "2017-03-19 20:01:33",
"ftime": "2017-03-19 20:01:33",
"context": "[云南丽江公司]小许派,本人签-已签收",
"location": null
},
{
"time": "2017-03-19 10:37:25",
"ftime": "2017-03-19 10:37:25",
"context": "[云南丽江公司]云南丽江公司-南门片区-派件中",
"location": null
},
{
"time": "2017-03-19 09:16:33",
"ftime": "2017-03-19 09:16:33",
"context": "[云南丽江公司]已到达-云南丽江公司",
"location": null
},
{
"time": "2017-03-19 09:16:22",
"ftime": "2017-03-19 09:16:22",
"context": "[云南丽江公司]已到达-云南丽江公司",
"location": null
},
{
"time": "2017-03-18 10:07:16",
"ftime": "2017-03-18 10:07:16",
"context": "[云南昆明航空部]已到达-云南昆明航空部",
"location": null
},
{
"time": "2017-03-18 10:07:12",
"ftime": "2017-03-18 10:07:12",
"context": "[云南昆明航空部]云南昆明航空部-已发往-云南丽江公司",
"location": null
},
{
"time": "2017-03-17 02:03:37",
"ftime": "2017-03-17 02:03:37",
"context": "[广东东莞中转部]广东东莞中转部-已装袋发往-云南昆明航空部",
"location": null
},
{
"time": "2017-03-16 23:14:29",
"ftime": "2017-03-16 23:14:29",
"context": "[广东东莞凤岗分部]广东东莞凤岗分部-已发往-广东东莞中转部",
"location": null
},
{
"time": "2017-03-16 22:08:38",
"ftime": "2017-03-16 22:08:38",
"context": "[广东东莞凤岗分部]广东东莞凤岗分部-刘国贤-已收件",
"location": null
}
]
}
Message.java
package example.com.huancuntest.entity;import java.util.Date;import java.util.List;/** * Created by csjy on 2017/5/9. */public class MessageEntity { private List<DataEntity> data; public List<DataEntity> getData() { return data; } public void setData(List<DataEntity> data) { this.data = data; }}
DataEntity.java
package example.com.huancuntest.entity;/** * Created by csjy on 2017/5/9. */public class DataEntity { private String time; private String context; public void setContext(String context) { this.context = context; } public void setTime(String time) { this.time = time; } public String getTime() { return time; } public String getContext() { return context; }}
最后在写一个用于存放相关数据的实体
TotalEntity.java
package example.com.huancuntest.entity;/** * Created by csjy on 2017/5/9. */public class TotalEntity { private String context; public String getTime() { return time; } public void setTime(String time) { this.time = time; } public String getContext() { return context; } public void setContext(String context) { this.context = context; } private String time;}RecyclerView的适配器:
package example.com.huancuntest;import android.content.Context;import android.support.v7.widget.RecyclerView;import android.util.Log;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.TextView;import java.util.List;import example.com.huancuntest.entity.TotalEntity;/** * Created by Administrator on 2017/5/9. */public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.MyViewHolder>{ private LayoutInflater inflater; private List<TotalEntity> mList; public RecyclerViewAdapter(Context context, List<TotalEntity> mList) { inflater = LayoutInflater.from(context); this.mList = mList; } @Override public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { MyViewHolder holder = new MyViewHolder(inflater.inflate(R.layout.item_activity_main,parent,false)); return holder; } @Override public void onBindViewHolder(MyViewHolder holder, int position) { holder.tvContent.setText(mList.get(position).getContext()); holder.tvTime.setText(mList.get(position).getTime()); } @Override public int getItemCount() { return mList.size(); } public class MyViewHolder extends RecyclerView.ViewHolder{ private TextView tvContent,tvTime; public MyViewHolder(View itemView) { super(itemView); tvContent = (TextView) itemView.findViewById(R.id.tv_content); tvTime = (TextView) itemView.findViewById(R.id.tv_time); } }}声明一个泛型为TotalEntity的List,在绑定数据的方法中通过TotalEntity的get方法提供数据。
MainActivity
package example.com.huancuntest;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.support.v7.widget.LinearLayoutManager;import android.support.v7.widget.RecyclerView;import android.util.Log;import android.widget.Toast;import com.android.volley.RequestQueue;import com.android.volley.Response;import com.android.volley.VolleyError;import com.android.volley.toolbox.JsonRequest;import com.android.volley.toolbox.Volley;import com.google.gson.Gson;import com.google.gson.JsonArray;import org.json.JSONArray;import org.json.JSONException;import org.json.JSONObject;import java.util.ArrayList;import java.util.List;import example.com.huancuntest.Util.ACache;import example.com.huancuntest.entity.DataEntity;import example.com.huancuntest.entity.MessageEntity;import example.com.huancuntest.entity.TotalEntity;public class MainActivity extends AppCompatActivity { private RecyclerView recyclerView; private RecyclerViewAdapter adapter; private List<TotalEntity> mList; private TotalEntity total; private Gson gson; private SPUtil spUtil; private ACache aCache; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); } private void initView() { recyclerView = (RecyclerView)this.findViewById(R.id.recycler_view); recyclerView.setLayoutManager(new LinearLayoutManager(this)); initData(); adapter = new RecyclerViewAdapter(this,mList); recyclerView.setAdapter(adapter); } private void initData() { mList = new ArrayList<TotalEntity>(); gson = new Gson(); spUtil = SPUtil.getInstance(); aCache = ACache.get(MainActivity.this); String company = "shentong"; String num = "227873745185"; if (NetUtil.isNetwork(this)){ RequestQueue queue = Volley.newRequestQueue(this); GsonRequest<MessageEntity> request = new GsonRequest<MessageEntity>( "http://www.kuaidi100.com/query?type="+company+"&postid="+num, MessageEntity.class, new Response.Listener<MessageEntity>() { @Override public void onResponse(MessageEntity response) { for (int i = 0; i < response.getData().size(); i++){ total = new TotalEntity(); DataEntity entity = response.getData().get(i); total.setContext(entity.getContext()); total.setTime(entity.getTime()); mList.add(total); } Log.d("tag", "response----" + response.getData().toString()); try { JSONArray jsonArray = new JSONArray(gson.toJson(response.getData())); aCache.put("test",jsonArray); } catch (JSONException e) { e.printStackTrace(); } } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Log.e("Tag", error.getMessage(),error); } }); queue.add(request); }else{ JSONArray jsonArray = aCache.getAsJSONArray("test"); for (int i = 0; i < jsonArray.length(); i++) { try { total = gson.fromJson(jsonArray.get(i).toString(), TotalEntity.class); Log.d("tag","json array-----" + jsonArray.get(i).toString()); Log.d("Tag","getContect----" + total.getContext()); Log.d("Tag","getTime----" + total.getTime()); mList.add(total); } catch (JSONException e) { e.printStackTrace(); } } } }}
在initData()方法中,首先判断有没有网络,如果有,利用volley获取网络中的数据,将获取到的数据添加进List中,并将数据存入缓存,如果没有网络,获取缓存中的数据,并将数据添加进List中。
判断是否有网络的类:
package example.com.huancuntest.Util;import android.content.Context;import android.net.ConnectivityManager;import android.net.NetworkInfo;/** * Created by csjy on 2017/5/9. * 判断是否有网络 */public class NetUtil { public static boolean isNetwork(Context context){ ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo info = manager.getActiveNetworkInfo(); if (info != null && info.isConnected()){ if (info.getState() == NetworkInfo.State.CONNECTED){ return true; } } return false; }}
使用SharedPreferances实现缓存
这里只改动了MainActivity.java
package example.com.huancuntest;import android.os.Build;import android.support.annotation.RequiresApi;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.support.v7.widget.LinearLayoutManager;import android.support.v7.widget.RecyclerView;import android.util.Log;import android.util.LruCache;import android.widget.Toast;import com.android.volley.RequestQueue;import com.android.volley.Response;import com.android.volley.VolleyError;import com.android.volley.toolbox.JsonRequest;import com.android.volley.toolbox.Volley;import com.google.gson.Gson;import com.google.gson.JsonArray;import org.json.JSONArray;import org.json.JSONException;import org.json.JSONObject;import java.util.ArrayList;import java.util.List;import example.com.huancuntest.Util.ACache;import example.com.huancuntest.Util.NetUtil;import example.com.huancuntest.Util.SPUtil;import example.com.huancuntest.Util.SpUtils;import example.com.huancuntest.entity.DataEntity;import example.com.huancuntest.entity.MessageEntity;import example.com.huancuntest.entity.TotalEntity;public class MainActivity extends AppCompatActivity { private RecyclerView recyclerView; private RecyclerViewAdapter adapter; private List<TotalEntity> mList; private TotalEntity total; private Gson gson; private SPUtil spUtil; private ACache aCache; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); } private void initView() { recyclerView = (RecyclerView)this.findViewById(R.id.recycler_view); recyclerView.setLayoutManager(new LinearLayoutManager(this)); initData(); adapter = new RecyclerViewAdapter(this,mList); recyclerView.setAdapter(adapter); } private void initData() { mList = new ArrayList<TotalEntity>(); gson = new Gson(); spUtil = SPUtil.getInstance(); aCache = ACache.get(MainActivity.this); String company = "shentong"; String num = "227873745185"; if (NetUtil.isNetwork(this)){ RequestQueue queue = Volley.newRequestQueue(this); GsonRequest<MessageEntity> request = new GsonRequest<MessageEntity>( "http://www.kuaidi100.com/query?type="+company+"&postid="+num, MessageEntity.class, new Response.Listener<MessageEntity>() { @RequiresApi(api = Build.VERSION_CODES.KITKAT) @Override public void onResponse(MessageEntity response) { for (int i = 0; i < response.getData().size(); i++){ total = new TotalEntity(); DataEntity entity = response.getData().get(i); total.setContext(entity.getContext()); total.setTime(entity.getTime()); mList.add(total); }// JSONArray jsonArray = new JSONArray(gson.toJson(response.getData()));// Log.d("tag", "jsonArray test == " + jsonArray);// aCache.put("test",jsonArray); spUtil.putJsonArray(MainActivity.this,"test",gson.toJson(response.getData())); Toast.makeText(MainActivity.this, "has network", Toast.LENGTH_SHORT).show(); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Log.e("Tag", error.getMessage(),error); } }); queue.add(request); }else{// JSONArray jsonArray = aCache.getAsJSONArray("test");// for (int i = 0; i < jsonArray.length(); i++) {// try {// total = gson.fromJson(jsonArray.get(i).toString(), TotalEntity.class);// Log.d("tag","json array-----" + jsonArray.get(i).toString());// Log.d("Tag","getContect----" + total.getContext());// Log.d("Tag","getTime----" + total.getTime());// mList.add(total);// } catch (JSONException e) {// e.printStackTrace();// }// } String test = spUtil.getJsonArray(MainActivity.this,"test",""); JSONArray jsonArray = null; try { jsonArray = new JSONArray(test); for (int i = 0; i < jsonArray.length(); i++){ total = gson.fromJson(jsonArray.get(i).toString(),TotalEntity.class); mList.add(total); } } catch (JSONException e) { e.printStackTrace(); } Toast.makeText(this, "no network", Toast.LENGTH_SHORT).show(); } }}initData()方法中,将网络返回的数据(response)通过sharedPreferances缓存至内存中,在没有网络的情况下直接从内存中读取,没网络情况下,首先实例化一个Json数组,将此json数组序列化为TotalEntity对象(通过gson.fromJosn()方法实现),最后将数据添加进List中。
package example.com.huancuntest.Util;import android.content.Context;import android.content.SharedPreferences;import android.util.Log;import org.json.JSONObject;/** * Created by csjy on 2017/5/10. */public class SPUtil { public static final String SP_NAME = "name"; private static SPUtil instance; private static SharedPreferences mSp; private JSONObject mJsonObject; private SPUtil() { } public static SPUtil getInstance() { if (instance == null) { synchronized (SPUtil.class) { if (instance == null) { instance = new SPUtil(); } } } return instance; } public String getJsonArray(Context context,String key, String defVal) { mSp = context.getSharedPreferences(SP_NAME,Context.MODE_PRIVATE); Log.d("TAG", "getJsonArray: " + mSp.getString(key,defVal)); return mSp.getString(key,defVal); } public void putJsonArray(Context context, String key, String value){ mSp = context.getSharedPreferences(SP_NAME,Context.MODE_PRIVATE); SharedPreferences.Editor editor = mSp.edit(); editor.putString(key,value); Log.d("tag","value====" + value); editor.commit(); }}
该类是一个单例模式。
putJsonArray()方法中,首先实例化sharedpreferances,调用Editor的putString()方法以键值对的形式添加数据。getJsonArray()方法调用sharedpreferances的getString()方法通过键值对的值来取值。
源码下载
阅读全文
1 0
- 几种缓存方案的实现
- 多线程-实现多线程的几种方案
- 实现横向排列的几种方案
- iOS多线程实现的几种方案
- java几种缓存的简单实现
- git.multi-gc的prune实现的几种方案
- 简易快速的实现远程通讯的几种方案
- 在BF561上实现h264编码的几种方案
- Python几种并发实现方案的性能比较
- 实现控件透明背景的几种方案
- 浅谈无线POS的几种实现方案
- .NET中AOP的几种实现方案
- AOP系列:.NET中AOP的几种实现方案
- Python几种并发实现方案的性能比较
- .NET中AOP的几种实现方案
- .NET中AOP的几种实现方案
- 实现Activity和Service通信的几种方案
- Java文件拷贝的几种实现方案
- kylin初识
- Segmentation fault到底是何方妖孽
- echo字符串的同时输出变量
- spring batch出现A job execution for this job is already running异常
- Qt中改变子窗口透明度
- 几种缓存方案的实现
- MyBatis参数传入集合之foreach动态sql
- 消息提示框
- MySQL server has gone away
- navicat快捷键
- Golang1.8编译静态库给C使用
- Trie树(2)
- spring自动装配
- HTML基础---认识标签(ul,ol,div,table,caption,dl,dt)