几种缓存方案的实现

越深入学习,越明白缓存的重要性,例举我认为的需要缓存的场景:

  • 从网络上获取的数据不会马上更新的情况,比如 快递信息就不会立马更新,这时候就可以使用缓存机制将获取到的数据缓存到内存,有网络情况下下拉刷新,无网络情况下从缓存中获取数据。
  • 一些阅读类,新闻类的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()方法通过键值对的值来取值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值