(安卓) 三级缓存具体逻辑(内存,磁盘{数据库},网络)

本文介绍了一种基于内存、本地数据库及网络请求的三级缓存机制实现方案,通过具体实例展示了如何利用内存缓存(LruCache)、本地数据库(GreenDao)和网络请求(OkHttp)来高效地管理和加载数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


三级缓存的主要概念就是:


思想:

               

1.从网络上获取数据,效率比较低,速度较慢,而且需要联网

2.为了更高的提高读取已经从网络上获取过的数据,并且在没联网的情况下也可以浏览,在第一次从网络上获取数据的时候将数据存储到缓存文件中

3.为了提高读取效率,直接从内存中读取是最快的,可以将获取的数据保存到内存中(LruCache),在内存足够的情况下,系统直接从内存中读取数据,效率是比较高的,当然,当内存不足的时候,系统会回收你在内存中保存在数据,这个时候你就需要从缓存文件中读取,如果缓存文件没有的情况下,你再从网络上获取。

优点:

1.对于读取你已经从网络上读取过的数据,使用三级缓存,可以大大提高读取数据的效率,

2.在没有联网的情况下你仍可以读取你保存的数据

3.不必每次都需要从网络上去获取数据,只是第一次访问的时候需要访问网络,节省了流量


一下代码用到了  数据库(GreenDao)     OKHttp的 get简单的解析(简洁版) ,    以及RecyclerView适配器

其实所用到解析或者适配器可以根据自己的需求改变  ,重要的是MainActivity 中的三级缓存逻辑


接下来就上代码:

        首先是

MainActivity类:

                                                            上俩个最主要的类:

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;

import com.facebook.drawee.backends.pipeline.Fresco;

import java.util.List;

import butterknife.BindView;
import butterknife.ButterKnife;
import bwie.com.sangjihuancun.gen.DataDao;

import static android.widget.LinearLayout.VERTICAL;

public class MainActivity extends AppCompatActivity {
    private static final String TAG="MainActivity";


    @BindView(R.id.recy)
    RecyclerView recy;
    private List<Data> datas;

    private String url = "http://120.27.23.105/product/getCatagory";
    private DataDao dao;
    private RecyclerViewAdpater  Adpater;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Fresco.initialize(this);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);

        //线性布局管理器     VERTICAL垂直 条目
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(MainActivity.this,VERTICAL,false );
        recy.setLayoutManager(linearLayoutManager);
//===============================================================
        dao = DbUtils.getInstance(this).getDao();

        //首先从内存中查看有没有数据
        datas = BaseAppLication.getInstance().getList();

        //适配器
        Adpater = new RecyclerViewAdpater(this,datas);
        recy.setAdapter( Adpater);
            if (datas == null|| datas.size()==0) {
            //如果没有从数据库中取
            List<Data> list = getDataFromDB();
            //如果数据库也是空的
            if (list == null || list.size() == 0) {
                //从网络中取数据
                getDataFromNet();
            } else {
                //否则数据库有数据添加到内存中
//             putDataToMemory(list);     //可以封装一个方法公用   不过为了理解的更清楚  所以分开写
                //清空集合中的数据
                datas.clear();
                // 将数据添加到数据库中
                datas.addAll(list);
                //属性适配器
                Adpater.notifyDataSetChanged();
                BaseAppLication.getInstance().setList(datas);
            }

        }
    }

    //从网络中取数据
    private void getDataFromNet() {

        HttpUtils.getInstance().get(url, new CallBack() {
            @Override
            public void onSuccess(Object o) {
                JsonRootBean bean = (JsonRootBean) o;
                if (bean != null) {
                    List<Data> data = bean.getData();
                    if (data != null) {
                        //将网络请求的数据存到内存和数据库中
                        //既然已经走到网络请求了,就把原来集合里面清空
                        datas.clear();
                        // 将网络请求的数据存到内存和数据库中
                        datas.addAll(data);
                        BaseAppLication.getInstance().setList(datas);
//                        putDataToMemory(data);       //可以封装一个方法公用   不过为了理解的更清楚  所以分开写
                        //添加到数据库
                        for (Data data1 : data) {
                            dao.insertOrReplace(data1);
                        }
                        //刷新适配器
                        Adpater.notifyDataSetChanged();
                    }
                }

            }
            @Override
            public void onFailes(Exception e) {

            }
        }, JsonRootBean.class);
    }

    //从数据库中取数据
    public List<Data> getDataFromDB() {
        List<Data> datas = dao.loadAll();
        Log.i(TAG,"aaaaa"+datas.size());
        return datas;
    }


    /**
     * 蒋数据添加到内存中
     *
     * @param data
     */
    private void putDataToMemory(List<Data> data) {
        Log.i(TAG, "向内存中存数据");

    }

}

BaseAppLication 类:
                                清单文件中配置  
                    android:name=".BaseAppLication"
import android.app.Application;

import java.util.ArrayList;
import java.util.List;


 
public class BaseAppLication extends Application {

    private  static BaseAppLication instance;
    private List<Data> list;

    @Override
    public void onCreate() {
        super.onCreate();
        instance=this;
    }

    public static  BaseAppLication getInstance(){
        return instance;
    }

    public List<Data> getList() {
        //如果集合是空的话,把它new出来,否则会报空指真
        if (list==null){
            list=new ArrayList<>();
        }
        return list;
    }

    public void setList(List<Data> list) {
        this.list = list;
    }
}
     

====================================================================================

接下来就是数据库的封装类和 OkHttp的封装类:

      首先   数据库封装类:

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;

import bwie.com.sangjihuancun.gen.DaoMaster;
import bwie.com.sangjihuancun.gen.DaoSession;
import bwie.com.sangjihuancun.gen.DataDao;

/**
 * Created by 迷人的脚毛!! on 2017/11/30.
 */

public class DbUtils {
    private static volatile DbUtils instance;
    private final DataDao dao;

    public DbUtils(Context context) {
        DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(context,"q",null);
        SQLiteDatabase writableDatabase = helper.getWritableDatabase();
        DaoMaster daoMaster = new DaoMaster(writableDatabase);
        DaoSession daoSession = daoMaster.newSession();

        dao = daoSession.getDataDao();


    }

    public static DbUtils getInstance(Context context){
        if (instance==null){
            synchronized (DbUtils.class){
                if (null==instance){
                    instance= new DbUtils(context);
                }
            }
        }
        return instance;
    }

    public DataDao getDao(){
        return dao;
    }
}


   OkHttp 封装类:

import android.os.Handler;

import com.google.gson.Gson;

import java.io.IOException;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

 

public class HttpUtils {

    private static volatile HttpUtils instance;
    private final OkHttpClient client;

    public HttpUtils() {
        client = new OkHttpClient();
    }

    private Handler handler=new Handler();
    public static HttpUtils getInstance(){
        if (instance==null){
            synchronized (HttpUtils.class){
                if (null==instance){
                    instance=new HttpUtils();
                }
            }
        }
        return instance;
    }

    public void get(String url, final CallBack  callBack, final Class cls)  {

        Request build = new Request.Builder()
                .url(url)
                .get()
                .build();


        Call call = client.newCall(build);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, final IOException e) {

                handler.post(new Runnable() {
                    @Override
                    public void run() {

                        callBack.onFailes(e);
                    }
                });
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {

                String s = response.body().string();
                Gson gson = new Gson();
                final Object o = gson.fromJson(s,cls);
                handler.post(new Runnable() {
                    @Override
                    public void run() {

                        callBack.onSuccess(o);

                    }
                });
            }
        });
    }
}


最后一个  适配器类:   

        

RecyclerViewAdpater类:

import android.content.Context;
import android.net.Uri;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.facebook.drawee.view.SimpleDraweeView;

import java.util.List;
 

public class RecyclerViewAdpater extends RecyclerView.Adapter<RecyclerViewAdpater.ViewHolder>{

    private Context context;
    private List<Data> list;

    public RecyclerViewAdpater(Context context, List<Data> list) {
        this.context = context;
        this.list = list;
    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        View v = View.inflate(context, R.layout.adpater, null);

        ViewHolder vv = new ViewHolder(v);
        return vv;
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        Uri uri = Uri.parse(list.get(position).getIcon());
        holder.img.setImageURI(uri);


        holder.name.setText(list.get(position).getName());
    }

    @Override
    public int getItemCount() {
        return list.size();
    }

    class ViewHolder extends RecyclerView.ViewHolder{

        private SimpleDraweeView img;
        private TextView name;
        public ViewHolder(View itemView) {
            super(itemView);

              img=(SimpleDraweeView)itemView.findViewById(R.id.img);
             name=(TextView) itemView.findViewById(R.id.name);
        }
    }
}


剩下的bean封装类就不写了,因为是更具所解析的数据对应的封装数据类  。最主要的就是最上面的俩个类的代码。

                  其次就是数据库(GreenDao)的用法可根据我上一篇博客进行参考!

                                    GreenDao 的增删改查   : http://blog.youkuaiyun.com/qq_40090482/article/details/78679035


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值