上一篇文章主要讲解了9GAG中的UI部分,这篇文章主要讲解客户端与服务器的数据交换。项目中的数据交换主要使用了Volley这个开源项目,关于Volley的讲解可以查看我之前写的博客,除了Volley以外,还使用了Universal-Image-Loader 进行图片的加载。

数据交换流程

整个数据交换的流程很简单,根据指定的API从服务器获得关于图片的数据,把数据存入数据库,图片做缓存,展示的时候先从数据库和缓存里找,没有的话再去服务器GET。

返回数据类型

字符

向服务器请求的地址
下面是返回的数据:

{
data: [
{
id: "a8jx9z6",
from: {
name: ""
},
caption: "When I changed my wifi password but somehow my neigbours still connect",
images: {
small: "",
normal: "http://img-9gag-fun.9cache.com/photo/a8jx9z6_460s.jpg",
large: "http://img-9gag-fun.9cache.com/photo/a8jx9z6_700b.jpg"
},
link: "http://9gag.com/gag/a8jx9z6",
actions: {
like: "http://9gag.com/vote/like/id/a8jx9z6",
dislike: "http://9gag.com/vote/dislike/id/a8jx9z6",
unlike: "http://9gag.com/vote/unlike/id/a8jx9z6"
},
votes: {
count: 13988
}
},
{
id: "aojvm3x",
from: {
name: ""
},
caption: "Showing computer to your crush",
images: {
small: "",
normal: "http://img-9gag-fun.9cache.com/photo/aRVbAV5_460s.jpg",
large: "http://img-9gag-fun.9cache.com/photo/aRVbAV5_700b.jpg"
},
link: "http://9gag.com/gag/aRVbAV5",
actions: {
like: "http://9gag.com/vote/like/id/aRVbAV5",
dislike: "http://9gag.com/vote/dislike/id/aRVbAV5",
unlike: "http://9gag.com/vote/unlike/id/aRVbAV5"
},
votes: {
count: 14551
}
},
{
id: "aAp8PwL",
from: {
name: ""
},
...
...
...
caption: "All I will probably love the new one as well. Don't understand all the hate.",
images: {
small: "",
normal: "http://img-9gag-fun.9cache.com/photo/avLKjy5_460s.jpg",
large: "http://img-9gag-fun.9cache.com/photo/avLKjy5_700b.jpg"
},
link: "http://9gag.com/gag/avLKjy5",
actions: {
like: "http://9gag.com/vote/like/id/avLKjy5",
dislike: "http://9gag.com/vote/dislike/id/avLKjy5",
unlike: "http://9gag.com/vote/unlike/id/avLKjy5"
},
votes: {
count: 12675
}
}
],
paging: {
next: "avLKjy5"
}
}

JSON封装

通过对服务器返回的数据分析得到每此返回的是一个JSON的字串,这个字串中包含了若干个图片的信息和最后一个paging的数据。再分析每个图片的信息可以发现,每个图片包含caption,images,votes等部分,其中image和votes又包含子信息。根据返回的数据和我们的需求设计出如下的Feed类

public class Feed extends BaseModel {private static final HashMap<String, Feed> CACHE = new HashMap<String, Feed>();private String id;private String caption;private String link;private Image images;private Vote votes;public class Image {public String small;public String normal;public String large;}private class Vote {public int count;}public static class FeedRequestData {public ArrayList<Feed> data;public Paging paging;public String getPage() {return paging.next;}}private class Paging {public String next;}......}

同个这个类,每次请求的数据都可以封装在一个FeedRequestData对象中,这样操作起来比单独解析每一个Feed会方便很多。

请求数据

 private void loadData(String next) {//request data from InternetRequestManager.INSTANCE.getRequestQueue().add(new GsonRequest<>(String.format(GagApi.LIST, "hot", next),Feed.FeedRequestData.class, null, new Response.Listener<Feed.FeedRequestData>() {final boolean isRefreshFromTop = ("0".equals(page));@Overridepublic void onResponse(final Feed.FeedRequestData response) {TaskUtil.executeAsyncTask(new AsyncTask<Object, Void, Void>() {@Overrideprotected Void doInBackground(Object... params) {if (isRefreshFromTop) {feedsDataHelper.deleteAll();}page = response.getPage();ArrayList<Feed> feeds = response.data;//write to dbfeedsDataHelper.bulkInsert(feeds);return null;}@Overrideprotected void onPostExecute(Void aVoid) {super.onPostExecute(aVoid);swipeLayout.setRefreshing(false);PageListView.isLoading = false;}});}}, new Response.ErrorListener() {@Overridepublic void onErrorResponse(VolleyError volleyError) {Log.e("FeedFragment","VolleyError" + volleyError.toString());swipeLayout.setRefreshing(false);}}));}

自定义了一个Gson Request用来解析Gson,注意下面两句

 page = response.getPage();ArrayList<Feed> feeds = response.data;

page对应的是JSON字串中的paging,而ArrayList feeds就是所有的图片信息,虽然只是一个对象但却包含了所有的图片信息,是不是很方便~

图片

关于图片的加载是在CursorAdapter的bindView()里完成的,利用的是Volley的图片加载技术,具体请参考这个文章:使用Volley加载图片

 mDefaultImageDrawable = new ColorDrawable(mResource.getColor(COLORS[cursor.getPosition() % COLORS.length]));holder.imageRequest = ImageCacheManager.loadImage(feed.images.normal, ImageCacheManager.getImageListener(holder.image, mDefaultImageDrawable, mDefaultImageDrawable), 0, DensityUtils.dip2px(context, IMAGE_MAX_HEIGHT));

上面还涉及了ImageCacheManager这个类,这个类主要负责图片加载和缓存的相关设置。
当然了,这里也可以使用Universal-Image-Loader来加载图片(其实我感觉使用这个更简洁一些…)

总结

本文讲解了9GAG中的网络数据交换的部分,主要是字符和图片两种类型的数据传输和Feed的结构设计,总体来说并不是很难,只要熟悉了Volley和了解了项目结构就能看懂源码中的这部分,下一篇文章将会讲解数据的缓存,包括字符串和图片两种格式,缓存是这个项目的难点,项目中很大一部分代码都与缓存有关,看懂了缓存就把整个项目都看懂了,还等什么,赶紧开始下一篇的阅读吧。

开源项目9GAG源码解析与Material改造(二)相关推荐

  1. BT开源项目Snark源码分析

    BT开源项目Snark源码分析 Snark是国外一个开源Java的项目,实现了BitTorrent协议,通过分析此项目的源程序,可以更利于我们更加深入的了解当前流行的BT软件的原理,进而可以指导我们的 ...

  2. 今年我读了四个开源项目的源码,来分享下心得

    今年来看了 RocketMQ.Kafka.Dubbo .Tomcat 的源码,之前也有读者询问过如何读源码,索性就来分享一下. 其实还看了一点点 Linux.Redis.jdk8,这几个阅读的目的和上 ...

  3. 开源项目实例源码_今年我读了四个开源项目的源码,来分享下心得

    今年来看了 RocketMQ.Kafka.Dubbo .Tomcat 的源码,之前也有读者询问过如何读源码,索性就来分享一下. 其实还看了一点点 Linux.Redis.jdk8,这几个阅读的目的和上 ...

  4. 鸿蒙开源源码,基于鸿蒙系统开源项目OpenHarmony源码静态分析

    #ifndef __scc #define __scc(X) ((long) (X)) // 转为long类型 typedef long syscall_arg_t; #endif #define _ ...

  5. Go实现的5G核心网开源项目free5gc源码分析系列 | Gopher Daily (2021.01.08) ʕ◔ϖ◔ʔ

    每日一谚:"Abstractions should be discovered, not created." Go技术新闻 Go实现的5G核心网开源项目free5gc源码分析系列 ...

  6. 【机器人学】机器人开源项目KDL源码学习:(5)KDL如何求解几何雅克比矩阵

    这篇文章试图说清楚两件事:1. 几何雅克比矩阵的本质:2. KDL如何求解机械臂的几何雅克比矩阵. 一.几何雅克比矩阵的本质 机械臂的关节空间的速度可以映射到执行器末端在操作空间的速度,这种映射可以通 ...

  7. 开源项目Telegram源码 Telegram for Android Source

    背景介绍 Telegram 是一款跨平台的即时通信软件,它的客户端是自由及开放源代码软件.用户可以相互交换加密与自毁消息,发送照片.影片等所有类型文件.官方提供手机版.桌面版和网页版等多种平台客户端. ...

  8. TiKV 源码解析系列文章(二)raft-rs proposal 示例情景分析

    作者:屈鹏 本文为 TiKV 源码解析系列的第二篇,按照计划首先将为大家介绍 TiKV 依赖的周边库 raft-rs .raft-rs 是 Raft 算法的 Rust 语言实现.Raft 是分布式领域 ...

  9. 区块链开源项目Asch源码初探

    Asch这个名字是 App Side Chain 的缩写. 是一种基于区块链跨链技术的应用开发平台,目前全部核心代码已经在GitHub上开源. 区块链是比特币的底层技术,但是名气低于比特币,但是个人认 ...

  10. 基于‘纯洁的微笑’开源项目 — Favorites 源码分析

    引言: 对于某语言不算熟悉的话自创项目是很痛苦的过程,即便笔者是一位掌握java的Android码农,对于java入门也是深感无力,毕竟语言是基础,但框架设计模式却与Android有出入,且学习成本较 ...

最新文章

  1. 燃!Java全球标准中国人参与制定,阿里成首个受邀中国公司
  2. ArcGIS API for JavaScript Bookmarks(书签)
  3. 领域模型命名规约【PO,VO,POJO,BO,DTO,DO,JavaBean】
  4. Razor与HTML混合输出陷阱与技巧
  5. python中enumerate()的理解
  6. C/C++只做经典编程语言
  7. 手动安装lzop压缩工具 - JerryMo06的专栏 - 博客频道 - CSDN.NET
  8. (zhuan) Building Convolutional Neural Networks with Tensorflow
  9. 木兰许可证专业解读及首批采用“木兰”开源项目列表
  10. Save as XPS in Office “12”
  11. 手动搭建vue2框架还有vue3框架
  12. Oracle sga、pga介绍改动
  13. SSAS事实表和维度表数据类型必须一致
  14. Gym 100633G Nano alarm-clocks
  15. 6步搞定To B产品竞品分析,值得收藏!
  16. 34款Firefox渗透测试插件
  17. getinfo怎么用php,PHP SplObjectStorage getinfo()用法及代码示例
  18. AR室内导航-Three.js
  19. Activiti6--入门学习--中间事件
  20. 文件管理大师android,文件管理大师

热门文章

  1. 百度搜索开户竞价推广如何写出优质创意?
  2. [转载]Spring zuul日志配置
  3. 计算机word排版素材,WORD基础排版素材
  4. 怎么读取cf卡id_simotion读写CF卡,保存/读取变量
  5. 谷歌学术搜索技巧:查找一个句子的某个空应该用什么词
  6. 硬盘柱面损坏怎么办_硬盘坏道屏蔽工具,详细教您如何修复硬盘坏道
  7. 安装office2010提示错误25541的解决方法
  8. 关于赛马的问题,25匹赛出前3名或者前5名
  9. 重学statistics,Cha3 Descriptive Statistics: numerical measures
  10. HTML页面制作中出现的问题,网页制作过程中的普遍问题分析