diycode 开放 API 也有几个月的时间了,很多小伙伴都说想要试试,但是迄今为止,只有一个完整的开源客户端,看看隔壁 “干货集中营” 的客户端数量,简直不能比啊。我觉得其中很大的原因就是 diycode 的 api 数量太多,使用起来也太过于复杂了,单单权限认证这一关就能让不少跃跃欲试的小伙伴望而却步。
为了解决这一难题,我将 diycode 的开放 API 进行了二次封装,以方便想要制作客户端的小伙伴们使用,经过比较“漫长”的摸索和设计,目前其基本架构已经成型了,差不多是下面这样子:
当然了,里面还有一些细节没有在图中进行展示,具体的实现结构要比上图稍微复杂那么一点点。
到今天为止,其 SDK 的结构已经基本成型了,只剩下一些体力活没有弄完,预计 3 月 12 号可以放出第一个版本的 SDK。
app 的开发还正在进行中,可能要多等几天,就能看到我开发的客户端了,不过为了测试 SDK 是否真的那么好用,我做了 3 个页面用于测试,看起来是下面的样子:
测试结果和预期差不多,目前 demo 中每个 Activity(Fragment) 的代码量不超过 200 行,其中包括一些简单的注释,与请求数据相关的核心代码不超过 50 行,以 topic 详情页为例(一些细节尚未处理):
在这个 Activity 里面向服务器请求了两次数据:
- 获取 topic 详情
- 获取 topic 回复列表
并且将请求回来的数据与相关的 View 关联,即便如此,代码量也没有超过 200 行。
public class TopicContentActivity extends BaseActivity implements View.OnClickListener {
public static String TOPIC = "topic";
private TopicReplyListAdapter mAdapter;
private Topic topic;
@Override
protected int getLayoutId() {
return R.layout.activity_topic_content;
}
@Override
protected void initViews(ViewHolder holder, View root) {
initTopicContentPanel(holder);
initRecyclerView(holder);
}
// 初始化 topic 内容面板的数据
private void initTopicContentPanel(ViewHolder holder) {
Intent intent = getIntent();
topic = (Topic) intent.getSerializableExtra(TOPIC);
if (null != topic) {
toastShort("获取 topic 成功");
User user = topic.getUser();
holder.setText(R.id.username, user.getLogin() + "(" + user.getName() + ")");
holder.setText(R.id.time, TimeUtil.computePastTime(topic.getUpdated_at()));
holder.setText(R.id.title, topic.getTitle());
holder.loadImage(this, user.getAvatar_url(), R.id.avatar);
holder.setOnClickListener(this, R.id.avatar, R.id.username);
// 发出获取 topic 详情和 topic 回复的请求
// TODO 分页加载回复的内容(鉴于目前回复数量并不多,此处采取一次性加载)
mDiycode.getTopic(topic.getId());
mDiycode.getTopicRepliesList(topic.getId(), null, topic.getReplies_count());
} else {
toastShort("获取 topic 失败");
}
}
private void initRecyclerView(ViewHolder holder) {
mAdapter = new TopicReplyListAdapter(this) {
@Override
public void setListener(int position, GcsViewHolder holder, TopicReply topic) {
super.setListener(position, holder, topic);
// TODO 此处设置监听器
}
};
RecyclerView recyclerView = holder.get(reply_list);
RecyclerViewUtil.init(this, recyclerView, mAdapter);
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onTopicDetail(GetTopicEvent event) {
if (event.isOk()) {
MarkdownView markdownView = mViewHolder.get(R.id.content);
markdownView.setMarkDownText(event.getBean().getBody());
}
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onTopicReplysList(GetTopicRepliesListEvent event) {
if (event.isOk()) {
List<TopicReply> replies = event.getBean();
mAdapter.addDatas(replies);
} else {
toastShort("获取回复失败");
}
}
@Override
protected void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
@Override
protected void onStop() {
super.onStop();
EventBus.getDefault().unregister(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.avatar:
case R.id.username:
if (null != topic) {
openActivity(UserActivity.class, UserActivity.USER, topic.getUser());
}
break;
}
}
}
可以看到,其逻辑结构相当简单,当然了,这些代码都是经过我高度浓缩精炼后的,具体的浓缩精炼方法会在后续开发日志中逐渐教给大家,当然了,直接去看源码也行,本次的 diycode 开发过程是全公开的,如果想关注 diycode 的更多细节,可以到 GitHub 查看。
如果想要了解我的话,可以关注我的微博和网站,详情见下方。