Retrofit网络请求+GreenDao数据缓存

一.要求

通过Retrofit进行网络请求数据,要求后两个参数(下方接口地址中的10和1)通过注解方式传进去,使用RecyclerView进行列表展示,请求到数据之后,使用GreenDao进行数据缓存,当进入页面时,先从数据库中取数据,进行展示,再进行网络请求,有数据就更新,没有网络情况下只显示数据库中数据。进入页面后判断网络状态,通过EventBus发送网络状态并Toast显示,使用ButterKnife进行视图注入,使用Fresco进行列表图片展示。

http://gank.io/api/data/Android/10/1

二,实现的代码

1.添加依赖

  在APP下的build.gradle

  

apply plugin: 'com.android.application'
apply plugin: 'org.greenrobot.greendao'//greendao的依赖

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })

    compile 'com.android.support:appcompat-v7:26.+'
    compile 'com.android.support.constraint:constraint-layout:1.0.2'
    testCompile 'junit:junit:4.12'
    compile 'com.squareup.retrofit2:retrofit:2.3.0'
    compile 'com.squareup.retrofit2:converter-gson:2.3.0'
    compile 'com.jakewharton:butterknife:8.8.1'
    annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
    compile 'org.greenrobot:greendao:3.2.2'
    compile 'org.greenrobot:eventbus:3.1.1'
    compile 'com.android.support:recyclerview-v7:26.0.0-alpha1'
    compile 'com.facebook.fresco:fresco:0.12.0'
}
greendao {
    schemaVersion 1
    daoPackage 'bwie.com.gen'
    targetGenDir 'src/main/java'
}

    在根 build.gradle下

buildscript {
    repositories {
        jcenter()
        mavenCentral()
    }
    dependencies {
        classpath 'org.greenrobot:greendao-gradle-plugin:3.2.2'

    
    }
}
在项目清单文件下

    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <!--允许程序访问有关GSM网络信息(-->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <!--使用wifi的权限-->
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />


2. RetrofitUtils(封装retrofit请求的单例模式)

public class RetrofitUtils {
    private static volatile RetrofitUtils instance;
    private Retrofit retrofit;

    private RetrofitUtils(String url){
        retrofit = new Retrofit.Builder()
                .addConverterFactory(GsonConverterFactory.create())
                .baseUrl(url)
                .build();
    }
    public static RetrofitUtils getInstance(String url) {
        if (null == instance){
            synchronized (RetrofitUtils.class){
                if (instance == null){
                    instance = new RetrofitUtils(url);
                }
            }
        }
        return instance;
    }
    public Retrofit getRetrofit() {
        return retrofit;
    }
}
3.封装数据库的单例模式

public class DbHelper {
    private static volatile DbHelper instance;
    private final ResultsBeanDao dao;

    private DbHelper(Context context){
        DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(context, "userName", null);
        SQLiteDatabase db = helper.getWritableDatabase();
        DaoMaster daoMaster = new DaoMaster(db);
        DaoSession daoSession = daoMaster.newSession();
        dao = daoSession.getResultsBeanDao();
    }

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

    public ResultsBeanDao getDao() {
        return dao;
    }
}
4.retrofit请求的接口类

public interface NewsUtilsInterface  {
    @GET("10/1")
    Call<NewsBean> getNewsData();//NewsBean是获取网络数据后的对数据封装的类
}
5.将数据存入内存中的application

public class BaseHelperApplition extends Application {
    private static BaseHelperApplition instance;
    private List<ResultsBean> list;
    @Override
    public void onCreate() {
        super.onCreate();
        Fresco.initialize(this);
        instance = this;
    }

    public static BaseHelperApplition getInstance() {
        return instance;
    }

    public List<ResultsBean> getList() {
        if (list == null){
            list = new ArrayList<>();
        }
        return list;
    }

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

}
6. Adapter类

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


    private Context context;
    private List<ResultsBean> list = new ArrayList<>();
    private static final String TAG = "RecyclerViewAdapter";
    //建立枚举 2个item 类型
    public enum ITEM_TYPE {
        ITEM1,
        ITEM2
    }

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

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        //加载Item View的时候根据不同TYPE加载不同的布局
        if (viewType == ITEM_TYPE.ITEM1.ordinal()) {
            return new Item1ViewHolder(View.inflate(context, R.layout.item, null));
        } else {
            return new Item2ViewHolder(View.inflate(context, R.layout.item2, null));
        }
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        if (holder instanceof Item1ViewHolder) {
            Uri uri = Uri.parse("http://img.gank.io/fef497ed-83ba-46f6-8a94-0e7b724e1c10");
            ((Item1ViewHolder) holder).myImageView.setImageURI(uri);
        } else if (holder instanceof Item2ViewHolder) {
            ((Item2ViewHolder) holder).name.setText(list.get(position).getWho());
            ((Item2ViewHolder) holder).title.setText(list.get(position).getDesc());
            ((Item2ViewHolder) holder).time.setText(list.get(position).getPublishedAt());

        }
    }

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

    @Override
    public int getItemViewType(int position) {
        //Enum类提供了一个ordinal()方法,返回枚举类型的序数,这里ITEM_TYPE.ITEM1.ordinal()代表0, ITEM_TYPE.ITEM2.ordinal()代表1
        List<String> images = list.get(position).getImages();
        return images != null? ITEM_TYPE.ITEM1.ordinal() : ITEM_TYPE.ITEM2.ordinal();
    }

    public static class Item1ViewHolder extends RecyclerView.ViewHolder {
        @BindView(R.id.my_image_view)
        SimpleDraweeView myImageView;

        public Item1ViewHolder(View itemView) {
            super(itemView);
            ButterKnife.bind(this, itemView);
        }
    }

    public static class Item2ViewHolder extends RecyclerView.ViewHolder {

        @BindView(R.id.name)
        TextView name;
        @BindView(R.id.title)
        TextView title;
        @BindView(R.id.time)
        TextView time;
        public Item2ViewHolder(View itemView) {
            super(itemView);
            ButterKnife.bind(this, itemView);
        }
    }
}
7.MainActivity类

public class MainActivity extends AppCompatActivity {

    private RecyclerView rv;
    private static final String TAG = "MainActivity";
    private RecyclerViewAdapter adapter;
    private ResultsBeanDao dao;
    private List<ResultsBean> datas;
    private List<ResultsBean> list = new ArrayList<>();
    private NetUtilsReceiver mReceiver;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        rv = (RecyclerView) findViewById(R.id.rv);
        dao = DbHelper.getInstance(this).getDao();
        datas = new BaseHelperApplition().getList();
        getData();
        adapter = new RecyclerViewAdapter(this, datas);
        rv.setLayoutManager(new LinearLayoutManager(this));
        rv.setAdapter(adapter);

        // 首先判断内存中有没有数据
        if (datas == null || datas.size()==0){
            // 从数据库中取
            List<ResultsBean> beanList = getFromDbHelper();
            // 判断数据库中也是空的
            if (beanList == null || beanList.size() == 0){
                //从网络中获取
                getData();
            }else{
                // 数据库中有数据的时候,存入内存
                putDataToMemory(beanList);
            }
        }
        initReceive();
        EventBus.getDefault().register(this);
    }
    public void getData() {
        Retrofit retrofit = RetrofitUtils.getInstance("http://gank.io/api/data/Android/").getRetrofit();
        NewsUtilsInterface newsUtilsInterface = retrofit.create(NewsUtilsInterface.class);
        Call<NewsBean> call = newsUtilsInterface.getNewsData();
        call.enqueue(new Callback<NewsBean>() {
            @Override
            public void onResponse(Call<NewsBean> call, Response<NewsBean> response) {
                List<ResultsBean> results = response.body().getResults();
                if (results!=null){
                    // 将网络请求的数据存到内存和数据库中
                    putDataToMemory(results);
                    for (ResultsBean data:results){
                        dao.insertOrReplace(data);
                    }
                }

            }

            @Override
            public void onFailure(Call<NewsBean> call, Throwable t) {

            }
        });

    }
    //存储数据到内存中
    private void putDataToMemory(List<ResultsBean> results) {
        datas.clear();
        datas.addAll(results);
        adapter.notifyDataSetChanged();
        BaseHelperApplition.getInstance().setList(results);
    }
    //查询数据库
    private List<ResultsBean> getFromDbHelper() {
        List<ResultsBean> resultsBeen = dao.loadAll();
        Log.i(TAG, "getFromDbHelper: "+resultsBeen);
        return resultsBeen;
    }
    public void initReceive() {
        mReceiver = new NetUtilsReceiver();
        IntentFilter mFilter = new IntentFilter();
        mFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
        registerReceiver(mReceiver, mFilter);
    }
    @Subscribe
    public void onEventMainThread(NetEvent event) {
       event.isNet();
    }
    
    @Override
    protected void onDestroy() {
        unregisterReceiver(mReceiver);
        EventBus.getDefault().unregister(this);
        super.onDestroy();
    }
}
8.判断网络的类

public class NetUtilsReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (ConnectivityManager.CONNECTIVITY_ACTION.equals(action)) {
            boolean isConnected = NetWorkUtils.isNetworkConnected(context);
            System.out.println("网络状态:" + isConnected);
            System.out.println("wifi状态:" + NetWorkUtils.isWifiConnected(context));
            System.out.println("移动网络状态:" + NetWorkUtils.isMobileConnected(context));
            System.out.println("网络连接类型:" + NetWorkUtils.getConnectedType(context));
            if (isConnected) {
                Toast.makeText(context, "已经连接网络", Toast.LENGTH_LONG).show();
                EventBus.getDefault().post(new NetEvent(true));
            } else {
                EventBus.getDefault().post(new NetEvent(false));
                Toast.makeText(context, "已经断开网络", Toast.LENGTH_LONG).show();
            }
        }
    }
}
public class NetEvent {
    public boolean isNet;

    public NetEvent(boolean isNet) {

        this.isNet = isNet;
    }

    public boolean isNet() {
        return isNet;
    }
}

public class NetWorkUtils {
    // 判断网络连接状态
    public static boolean isNetworkConnected(Context context) {
        if (context != null) {
            ConnectivityManager mConnectivityManager = (ConnectivityManager) context
                    .getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo mNetworkInfo = mConnectivityManager
                    .getActiveNetworkInfo();
            if (mNetworkInfo != null) {
                return mNetworkInfo.isAvailable();
            }
        }
        return false;
    }

    // 判断wifi状态
    public static boolean isWifiConnected(Context context) {
        if (context != null) {
            ConnectivityManager mConnectivityManager = (ConnectivityManager) context
                    .getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo mWiFiNetworkInfo = mConnectivityManager
                    .getNetworkInfo(ConnectivityManager.TYPE_WIFI);
            if (mWiFiNetworkInfo != null) {
                return mWiFiNetworkInfo.isAvailable();
            }
        }
        return false;
    }

    // 判断移动网络
    public static boolean isMobileConnected(Context context) {
        if (context != null) {
            ConnectivityManager mConnectivityManager = (ConnectivityManager) context
                    .getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo mMobileNetworkInfo = mConnectivityManager
                    .getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
            if (mMobileNetworkInfo != null) {
                return mMobileNetworkInfo.isAvailable();
            }
        }
        return false;
    }
    // 获取连接类型
    public static int getConnectedType(Context context) {
        if (context != null) {
            ConnectivityManager mConnectivityManager = (ConnectivityManager) context
                    .getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo mNetworkInfo = mConnectivityManager
                    .getActiveNetworkInfo();
            if (mNetworkInfo != null && mNetworkInfo.isAvailable()) {
                return mNetworkInfo.getType();
            }
        }
        return -1;
    }
    /**
     * 设置网络
     * @param paramContext
     */
    public static void startToSettings(Context paramContext) {
        if (paramContext == null)
            return;
        try {
            if (Build.VERSION.SDK_INT > 10) {
                paramContext.startActivity(new Intent(
                        "android.settings.SETTINGS"));
                return;
            }
        } catch (Exception localException) {
            localException.printStackTrace();
            return;
        }
        paramContext.startActivity(new Intent(
                "android.settings.WIRELESS_SETTINGS"));
    }
}














评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值