Model层
public class MyModel { public interface NewCall{ void OnSuccess(FuLi fuLi); } NewCall newCall; public void getNewModel(NewCall newCall){ this.newCall=newCall; } Handler handler=new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); if(msg.what==0){ FuLi fuLi= (FuLi) msg.obj; if(newCall!=null){ newCall.OnSuccess(fuLi); } } } }; public void getModel(int page){ HttpLoggingInterceptor httpLoggingInterceptor=new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() { @Override public void log(String message) { // Log.d("xxx",message); } }); httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY); OkHttpClient okHttpClient=new OkHttpClient.Builder().addInterceptor(httpLoggingInterceptor).build(); Retrofit retrofit=new Retrofit.Builder().client(okHttpClient).addConverterFactory(GsonConverterFactory.create()) .baseUrl(Api.url).build(); App app = retrofit.create(App.class); Call<FuLi> fuLi = app.getFuLi(page); fuLi.enqueue(new Callback<FuLi>() { @Override public void onResponse(Call<FuLi> call, Response<FuLi> response) { FuLi body = response.body(); Message message=new Message(); message.what=0; message.obj=body; handler.sendMessage(message); } @Override public void onFailure(Call<FuLi> call, Throwable t) { } }); } }
Presenter层
public class MyPresenter { MyModel myModel; MyView myView; public MyPresenter(MyView myView) { this.myView = myView; myModel=new MyModel(); } public void getPresenter(int page){ myModel.getModel(page); myModel.getNewModel(new MyModel.NewCall() { @Override public void OnSuccess(FuLi fuLi) { myView.OnSuccess(fuLi); } }); } }
View层
public interface MyView { void OnSuccess(FuLi fuLi); }
Api
public class Api { public static String url="http://gank.io/api/"; }
App GET请求
public interface App { @GET("data/%E7%A6%8F%E5%88%A9/10/{page}") Call<FuLi> getFuLi(@Path("page") int page); }
MyUserDao Application
public class MyUserDao extends Application { public static MyUserDao myApp; private DaoMaster.DevOpenHelper devOpenHelper; private SQLiteDatabase writableDatabase; private DaoMaster daoMaster; private DaoSession daoSession; @Override public void onCreate() { super.onCreate(); myApp=this; setDb(); } public static MyUserDao getMyApp(){ return myApp; } public void setDb(){ devOpenHelper = new DaoMaster.DevOpenHelper(this, "jiajilong.db", null); writableDatabase = devOpenHelper.getWritableDatabase(); daoMaster = new DaoMaster(writableDatabase); daoSession = daoMaster.newSession(); } public DaoSession getDaoSession(){ return daoSession; } public SQLiteDatabase getWritableDatabase(){ return writableDatabase; } }
适配器
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHodler> { Context context; List<ResultsBean> results; public MyAdapter(Context context, List<ResultsBean> results) { this.context = context; this.results = results; } @Override public MyViewHodler onCreateViewHolder(ViewGroup parent, int viewType) { View inflate = LayoutInflater.from(context).inflate(R.layout.item, parent, false); MyViewHodler myViewHodler=new MyViewHodler(inflate); return myViewHodler; } @Override public void onBindViewHolder(MyViewHodler holder, int position) { ResultsBean resultsBean = results.get(position); String url = resultsBean.getUrl(); Glide.with(context).load(url).into(holder.imageView); String type = resultsBean.getType(); holder.textView.setText(type); } @Override public int getItemCount() { return results.size(); } public class MyViewHodler extends RecyclerView.ViewHolder{ public final TextView textView; public final ImageView imageView; public MyViewHodler(View itemView) { super(itemView); textView = (TextView) itemView.findViewById(R.id.text); imageView = (ImageView) itemView.findViewById(R.id.img); } } }
bean类数据库属性类就是这个类最里层的那个
public class FuLi { /** * error : false * results : [{"_id":"5aa5cc6a421aa9103ed33c7c","createdAt":"2018-03-12T08:40:10.360Z","desc":"3-12","publishedAt":"2018-03-12T08:44:50.326Z","source":"chrome","type":"福利","url":"https://ws1.sinaimg.cn/large/610dc034ly1fp9qm6nv50j20u00miacg.jpg","used":true,"who":"daimajia"},{"_id":"5a8e0c41421aa9133298a259","createdAt":"2018-02-22T08:18:09.547Z","desc":"2-22","publishedAt":"2018-02-22T08:24:35.209Z","source":"chrome","type":"福利","url":"https://ws1.sinaimg.cn/large/610dc034ly1foowtrkpvkj20sg0izdkx.jpg","used":true,"who":"代码家"},{"_id":"5a7b93d2421aa90d2cd3d7f8","createdAt":"2018-02-08T08:03:30.905Z","desc":"2-8","publishedAt":"2018-02-08T08:13:24.479Z","source":"chrome","type":"福利","url":"http://7xi8d6.com1.z0.glb.clouddn.com/20180208080314_FhzuAJ_Screenshot.jpeg","used":true,"who":"daimajia"},{"_id":"5a6e5f88421aa9115696004f","createdAt":"2018-01-29T07:40:56.269Z","desc":"1-29","publishedAt":"2018-01-29T07:53:57.676Z","source":"chrome","type":"福利","url":"http://7xi8d6.com1.z0.glb.clouddn.com/20180129074038_O3ydq4_Screenshot.jpeg","used":true,"who":"daimajia"},{"_id":"5a65381a421aa91156960022","createdAt":"2018-01-22T09:02:18.715Z","desc":"1-22","publishedAt":"2018-01-23T08:46:45.132Z","source":"chrome","type":"福利","url":"http://7xi8d6.com1.z0.glb.clouddn.com/20180122090204_A4hNiG_Screenshot.jpeg","used":true,"who":"daimajia"},{"_id":"5a5bfc29421aa9115489927b","createdAt":"2018-01-15T08:56:09.429Z","desc":"1-15","publishedAt":"2018-01-16T08:40:08.101Z","source":"chrome","type":"福利","url":"http://7xi8d6.com1.z0.glb.clouddn.com/20180115085556_8AeReR_taeyeon_ss_15_1_2018_7_58_51_833.jpeg","used":true,"who":"daimajia"},{"_id":"5a5411fb421aa90fef2035f3","createdAt":"2018-01-09T08:51:07.91Z","desc":"1-9","publishedAt":"2018-01-10T07:57:19.486Z","source":"chrome","type":"福利","url":"http://7xi8d6.com1.z0.glb.clouddn.com/20180109085038_4A7atU_rakukoo_9_1_2018_8_50_25_276.jpeg","used":true,"who":"daimajia"},{"_id":"5a443fcb421aa90fe72536ed","createdAt":"2017-12-28T08:50:19.747Z","desc":"12-28","publishedAt":"2018-01-04T13:45:57.211Z","source":"chrome","type":"福利","url":"http://7xi8d6.com1.z0.glb.clouddn.com/20171228085004_5yEHju_Screenshot.jpeg","used":true,"who":"代码家"},{"_id":"5a4ad432421aa90fe2f02d1a","createdAt":"2018-01-02T08:37:06.235Z","desc":"1-2","publishedAt":"2018-01-02T08:43:32.216Z","source":"chrome","type":"福利","url":"http://7xi8d6.com1.z0.glb.clouddn.com/20180102083655_3t4ytm_Screenshot.jpeg","used":true,"who":"daimajia"},{"_id":"5a431acd421aa90fe50c02a8","createdAt":"2017-12-27T12:00:13.664Z","desc":"12-27","publishedAt":"2017-12-27T12:13:22.418Z","source":"chrome","type":"福利","url":"http://7xi8d6.com1.z0.glb.clouddn.com/20171227115959_lmlLZ3_Screenshot.jpeg","used":true,"who":"daimajia"}] */ private boolean error; private List<ResultsBean> results; public boolean isError() { return error; } public void setError(boolean error) { this.error = error; } public List<ResultsBean> getResults() { return results; } public void setResults(List<ResultsBean> results) { this.results = results; } }
数据库属性类就是接口里最内部的那个类
@Entity public class ResultsBean { /** * _id : 5aa5cc6a421aa9103ed33c7c * createdAt : 2018-03-12T08:40:10.360Z * desc : 3-12 * publishedAt : 2018-03-12T08:44:50.326Z * source : chrome * type : 福利 * url : https://ws1.sinaimg.cn/large/610dc034ly1fp9qm6nv50j20u00miacg.jpg * used : true * who : daimajia */ 原来的_id是字符串类型,把他注释掉,自己从新建一个Long类型id,如果本来的id是数字就可以使用,
如果不可以就在创建id /* private String _id;*/ @Id private Long id; @Property(nameInDb = "createdAt") private String createdAt; @Property(nameInDb = "desc") private String desc; @Property(nameInDb = "publishedAt") private String publishedAt; @Property(nameInDb = "source") private String source; @Property(nameInDb = "type") private String type; @Property(nameInDb = "url") private String url; @Property(nameInDb = "used") private boolean used; @Property(nameInDb = "who") private String who; @Generated(hash = 839516623) public ResultsBean(Long id, String createdAt, String desc, String publishedAt, String source, String type, String url, boolean used, String who) { this.id = id; this.createdAt = createdAt; this.desc = desc; this.publishedAt = publishedAt; this.source = source; this.type = type; this.url = url; this.used = used; this.who = who; } @Generated(hash = 1822271928) public ResultsBean() { } public Long getId() { return this.id; } public void setId(Long id) { this.id = id; } public String getCreatedAt() { return this.createdAt; } public void setCreatedAt(String createdAt) { this.createdAt = createdAt; } public String getDesc() { return this.desc; } public void setDesc(String desc) { this.desc = desc; } public String getPublishedAt() { return this.publishedAt; } public void setPublishedAt(String publishedAt) { this.publishedAt = publishedAt; } public String getSource() { return this.source; } public void setSource(String source) { this.source = source; } public String getType() { return this.type; } public void setType(String type) { this.type = type; } public String getUrl() { return this.url; } public void setUrl(String url) { this.url = url; } public boolean getUsed() { return this.used; } public void setUsed(boolean used) { this.used = used; } public String getWho() { return this.who; } public void setWho(String who) { this.who = who; } }
网络判断工具类
public static boolean isNetWorkAvailable(Context context) { //得到网络连接管理器 ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(context.CONNECTIVITY_SERVICE); //网络信息 NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo(); if (networkInfo != null) { return true; } return false; }
Activity
public class MainActivity extends AppCompatActivity implements MyView{ private RecyclerView mRlv; private SwipyRefreshLayout mSrl; int page=1; Handler handler; private ResultsBeanDao resultsBeanDao; List<ResultsBean> results2; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); handler=new Handler();
得到数据库 resultsBeanDao = MyUserDao.getMyApp().getDaoSession().getResultsBeanDao(); mRlv.setLayoutManager(new LinearLayoutManager(this)); mSrl.setColorSchemeResources(R.color.colorAccent); mSrl.setDirection(SwipyRefreshLayoutDirection.BOTH); final MyPresenter myPresenter=new MyPresenter(this); myPresenter.getPresenter(page);
得到网络工具类 boolean netWorkAvailable = Utils.isNetWorkAvailable(this);
查询数据库得到数据库里的数据
List<ResultsBean> resultsBeen = resultsBeanDao.loadAll();
在是false时没网时
if(!netWorkAvailable){
数据库不等于0时证明有缓存 if(resultsBeen.size()!=0){
把数据库里的数据给适配器 MyAdapter myAdapter=new MyAdapter(this,resultsBeen); mRlv.setAdapter(myAdapter); Toast.makeText(this, "有缓存", Toast.LENGTH_SHORT).show(); }else{
没网没缓存时 Toast.makeText(this, "无缓存", Toast.LENGTH_SHORT).show(); } } mSrl.setOnRefreshListener(new SwipyRefreshLayout.OnRefreshListener() {
刷新 @Override public void onRefresh(int index) { page=1; handler.postDelayed(new Runnable() { @Override public void run() { myPresenter.getPresenter(page); mSrl.setRefreshing(false); } },2000); } 加载 @Override public void onLoad(int index) { page++; handler.postDelayed(new Runnable() { @Override public void run() { myPresenter.getPresenter(page); mSrl.setRefreshing(false); } },2000); } }); } private void initView() { mRlv = (RecyclerView) findViewById(R.id.rlv); mSrl = (SwipyRefreshLayout) findViewById(R.id.srl); } @Override public void OnSuccess(FuLi fuLi) { List<ResultsBean> results = fuLi.getResults();
在page等于1时if( page== 1){
创建新集合 results2=new ArrayList<>(); }
把加载数据叠加到一块放入集合
results2.addAll(results);
在page等于1时 if(page==1){
把数据库里的数据清一清
resultsBeanDao.deleteAll();
循环缓存到数据库 for (int i = 0; i <results.size() ; i++) { resultsBeanDao.insert(results.get(i)); } Toast.makeText(MainActivity.this, "缓存成功", Toast.LENGTH_SHORT).show(); } MyAdapter myAdapter=new MyAdapter(this,results2); mRlv.setAdapter(myAdapter); } }
主布局
<?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:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.bw.greendaoretrofit2.MainActivity"> <com.bawei.swiperefreshlayoutlibrary.SwipyRefreshLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/srl" > <android.support.v7.widget.RecyclerView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/rlv" ></android.support.v7.widget.RecyclerView> </com.bawei.swiperefreshlayoutlibrary.SwipyRefreshLayout> </RelativeLayout>
子布局
<?xml version="1.0" encoding="utf-8"?> <LinearLayout 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="wrap_content" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:orientation="vertical" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.bw.greendaoretrofit2.MainActivity"> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/img" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/text" /> </LinearLayout>