几种缓存方案的实现

来源:互联网 发布: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.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中。

SpUtil.java如下:
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()方法通过键值对的值来取值。
源码下载

原创粉丝点击