Retrofit网络请求+GreenDao数据缓存

来源:互联网 发布:射手播放器 for mac 编辑:程序博客网 时间:2024/05/21 06:26

一.要求

通过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"));    }}