一.要求
通过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" />
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"));
}
}