一直以来都感觉自己只会看代码,解决bug,总是觉得自己能力有限,想做一些程序性的开发,但总是做到一半就戛然而止。这次终于鼓起勇气来从零开始做一款客户端程序,一切从零开始。
由于从来没有做过相应的开发,不敢说自己怎么组织架构,怎么设计项目等,都是随着项目慢慢的深入,一步步发掘项目功能,然后不断改进的结果。这个系列的文章,权当是某人的思路。
数据
首先我先想到的不是界面,而是数据,数据从什么地方来,应该怎么使用?很显然我们这个项目使用的是干活集中营的API,具体可以看http://gank.io/api
由于是网络数据,很自然就想到了okHttp了,当然你可能想到了RxJava+Retrofit,可是为了从基本入手,我就选择了okHttp了。
先简单装一下okHttp
- 导入okHttp包
只需在Gradle下添加如下依赖即可:
compile 'com.squareup.okhttp3:okhttp:3.6.0'
- 创建Manager类
我这里创建的是GankHttpManager.java,这里我将其改为单例类型。
private static GankHttpManager mInstance;
private GankHttpManager() {
}
public static GankHttpManager getInstance() {
if(mInstance == null) {
synchronized (GankHttpManager.class) {
if(mInstance == null) {
mInstance = new GankHttpManager();
}
}
}
return mInstance;
}
当然GankHttpManage不可能这么简单,既然是封装okHttp,当然得需要OkHttpClient,解析数据也需要Gson,这些一并在构造方法中初始化即可:
private OkHttpClient mHttpClient;
private Handler mHandler;
private Gson mGson;
private GankHttpManager() {
mHttpClient = new OkHttpClient();
mHandler = new Handler(Looper.getMainLooper());
mGson = new Gson();
}
这样我们的GankHttpManager就封装好了。现在我们要做的事情就是通过Gson来解析数据了。
通过查看干活集中营的Api,可以发现暂时我们需要的Api有两种类型,1. 每日数据;2.分类数据。通过查看json数据可以发现这两种Api的数据有些不一样。
每日数据(http://gank.io/api/day/年/月/日)
我们先来看一下json数据
//省略号代表后面的重复性内容省略
{
"category": [
"Android", ...
],
"error": false,
"results": {
"Android": [
{
"_id": "590af3b3421aa90c7fefdd3c", ...
}, ...
],...
}
}
如果用Gson进行解析那么我们应该怎样去构建对象呢?
可以看到整个json包含三个大括号,如果我们把大括号代表一个层级的话,那么就比较好分析了,
1.首先构建一个对象包含三个参数,category,error,results。那么最外层也就分析完了,
2.其次再看category,该对象中又包含中括号,那么我们可以将之看作为一个List。再看results,你会发现其和包含的内容和外层类似,可以把整个的result看做一个对象。这时你可能又郁闷了,如果把里面的每一个看做一个对象,但是对象里的内容又是重复的,这怎么解决呢?其实可以把result看做是几个不同的List就可以了。
经过简单的分析那么我开始构建我们的数据吧。首先构建的是最里层相似的内容。我将之封装为Gank对象。
public class Gank{
public String _id;
public Date createdAt;
public String desc;
public Date publishedAt;
public String source;
public String type;
public String url;
public boolean used;
public String who;
}
也可以加上@SerializedName的注解,来标明对应json的数据。
做完上面的工作,我们就可以来封装整个json了,我将之封装为DailyGank对象
public class DailyGank {
@SerializedName("category") public List<String> category;
@SerializedName("error") public boolean error;
@SerializedName("results") public Result result;
public class Result {
@SerializedName("福利") public List<Gank> welfareList;
@SerializedName("Android") public List<Gank> androidList;
@SerializedName("iOS") public List<Gank> iosList;
@SerializedName("拓展资源") public List<Gank> extraList;
@SerializedName("前端") public List<Gank> frontList;
@SerializedName("瞎推荐") public List<Gank> casualList;
@SerializedName("App") public List<Gank> appList;
@SerializedName("休息视频") public List<Gank> videoList;
}
}
这样我们就封装了每日数据的json对象,那么下面我们来封装分类对象
分类对象(http://gank.io/api/data/数据类型/请求个数/第几页)
同样,我们可以看一下json数据
{
"error": false,
"results": [
{
"_id": "590af3b3421aa90c7fefdd3c",...
}, ...
]
}
可以看到和上面的数据有一点出入,也有相似点。我就不介绍了。直接看封装ClassifyGank
public class ClassifyGank {
@SerializedName("error") public boolean error;
@SerializedName("results") public List<Gank> classifyGank;
}
或者我们可以将DailyGank和ClassifyGank中共有的属性error给封装到BaseGank中,然后继承。不这样也没有关系。
既然我们的json数据已经分析清楚了,那么就可以在GankHttpManager中来获取并解析数据了。主要写两个方法,分别获取每日数据和分类数据
public void getClassifyGank(String url, final GankHttpListener listener) {
Request request = new Request.Builder().url(url).build();
mHttpClient.newCall(request)
.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
final String body = response.body().string();
mHandler.post(new Runnable() {
@Override
public void run() {
ClassifyGank data = mGson.fromJson(body,ClassifyGank.class);
// TODO: 处理数据
}
});
}
});
}
public void getDailyGank(String url, final GankHttpListener listener){
Request request = new Request.Builder().url(url).build();
mHttpClient.newCall(request)
.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
final String body = response.body().string();
mHandler.post(new Runnable() {
@Override
public void run() {
DailyGank data = mGson.fromJson(body,DailyGank.class);
// TODO: 处理数据
}
});
}
});
}
代码中有一段注释是用来处理数据用的,看见了吗?在我们传入方法的地方都有一个listener,那个就是用来进行回调的方法,以便我们得到数据后进行处理。后面会介绍该listener怎么去定义。
这次就先讲到这里,下面一节讲解Gank客户端的主界面。拜拜!