Skip to content

Latest commit

 

History

History
132 lines (103 loc) · 5.55 KB

journal-01.md

File metadata and controls

132 lines (103 loc) · 5.55 KB

01 - 整体架构

diycode 开放 API 也有几个月的时间了,很多小伙伴都说想要试试,但是迄今为止,只有一个完整的开源客户端,看看隔壁 “干货集中营” 的客户端数量,简直不能比啊。我觉得其中很大的原因就是 diycode 的 api 数量太多,使用起来也太过于复杂了,单单权限认证这一关就能让不少跃跃欲试的小伙伴望而却步。

为了解决这一难题,我将 diycode 的开放 API 进行了二次封装,以方便想要制作客户端的小伙伴们使用,经过比较“漫长”的摸索和设计,目前其基本架构已经成型了,差不多是下面这样子:

SDK 结构

当然了,里面还有一些细节没有在图中进行展示,具体的实现结构要比上图稍微复杂那么一点点。

到今天为止,其 SDK 的结构已经基本成型了,只剩下一些体力活没有弄完,预计 3 月 12 号可以放出第一个版本的 SDK。

app 的开发还正在进行中,可能要多等几天,就能看到我开发的客户端了,不过为了测试 SDK 是否真的那么好用,我做了 3 个页面用于测试,看起来是下面的样子:

测试结果和预期差不多,目前 demo 中每个 Activity(Fragment) 的代码量不超过 200 行,其中包括一些简单的注释,与请求数据相关的核心代码不超过 50 行,以 topic 详情页为例(一些细节尚未处理):

在这个 Activity 里面向服务器请求了两次数据:

  1. 获取 topic 详情
  2. 获取 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 查看。

如果想要了解我的话,可以关注我的微博和网站,详情见下方。

微博: http://weibo.com/GcsSloop
网站: http://www.gcssloop.com