1、建立网络连接的基本方式

Android中建立网络连接最主要的方式是利用HttpURLConnection,示例如下:

public class HttpUtil {public static byte[] getUrlBytes(String urlSpec) throws IOException {//将地址信息封装成URLURL url = new URL(urlSpec);//创建指向URL链接的HttpURLConnection对象HttpURLConnection connection = (HttpURLConnection) url.openConnection();try {//保存返回结果ByteArrayOutputStream out = new ByteArrayOutputStream();//真正开始访问指定地址InputStream in = connection.getInputStream();//HTTP_OK才是成功建立链接if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {throw new IOException(connection.getResponseMessage() +": with " +urlSpec);}int bytesRead;byte[] buffer = new byte[1024];//不断从网络下载数据,并保存到out中while ((bytesRead = in.read(buffer)) > 0) {out.write(buffer, 0, bytesRead);}out.close();//下载完毕后,将结果转化成byte arrayreturn out.toByteArray();} finally {//断开连接connection.disconnect();}}public static String getUrlString(String urlSpec) throws IOException{//将byteArray转化为Stringreturn new String(getUrlBytes(urlSpec));}
}

2、下载百度图片对应的JSON数据

我们进入百度图片,例如“微距摄影”这个类别,其http地址如下:

http://image.baidu.com/search/index?tn=baiduimage&ipn=r&ct=201326592&cl=2&lm=-1&st=-1&sf=2&fmq=1480332039000_R_D&pv=&ic=0&nc=1&z=&se=&showtab=0&fb=0&width=&height=&face=0&istype=2&ie=utf-8&word=%E5%BE%AE%E8%B7%9D%E6%91%84%E5%BD%B1

其中:

http://image.baidu.com/search/index?

可以看作基础的http地址,后续的tn、ipn、ct等均是额外的访问参数。
例如:word后就是访问的类别,对应中文的“微距摄影”。

现在,基于这个地址,我们来看看如何获取百度图片搜索得到的结果:

public List<GalleryItem> fetchItems() {..............try {//解析基础地址String url = Uri.parse("http://image.baidu.com/search/index?").buildUpon()//增加参数,这里指定结果以json格式返回.appendQueryParameter("tn", "resultjson")//指定类别为微距摄影.appendQueryParameter("word", "微距摄影").build().toString();Log.d("ZJTest", url);String jsonString = HttpUtil.getUrlString(url);Log.d("ZJTest", jsonString);............} catch (JSONException | IOException e) {e.printStackTrace();}return items;
}

我们增加了log信息,看看生成的url:

02-14 09:59:49.154 32471-32506/stark.a.is.zhang.photogallery D/ZJTest: http://image.baidu.com/search/index?tn=resultjson&word=%E5%BE%AE%E8%B7%9D%E6%91%84%E5%BD%B1

可以看到,url的信息结构与前面的http地址相似。
这里我们只使用了tn、word参数,还可以按照同样的方式,增加其它的要求。

我们再看看返回的结果,为了方便观察,我们修改一下返回结果的格式,增加一些回车和空格:

02-14 09:59:49.354 32471-32506/stark.a.is.zhang.photogallery D/ZJTest:
{
"queryEnc":"%E5%BE%AE%E8%B7%9D%E6%91%84%E5%BD%B1",
"queryExt":"微距摄影",
"listNum":1965,
"displayNum":208527,
"gsm":"1000000001e",
"bdSearchTime":"",
"isNeedAsyncRequest":0,
"bdIsClustered":"1",
"data":[
{
"thumbURL":"http://f.hiphotos.baidu.com/image/h%3D300/sign=e444f9f5a0014c08063b2ea53a7a025b/359b033b5bb5c9ea18ae77bfdc39b6003af3b308.jpg",
"middleURL":"http://f.hiphotos.baidu.com/image/h%3D200/sign=1250a848b199a90124355c362d940a58/359b033b5bb5c9ea18ae77bfdc39b6003af3b308.jpg",    "largeTnImageUrl":"",
"hasLarge" :0,    "hoverURL":"http://f.hiphotos.baidu.com/image/h%3D300/sign=e444f9f5a0014c08063b2ea53a7a025b/359b033b5bb5c9ea18ae77bfdc39b6003af3b308.jpg",    "pageNum":0,
"objURL":"http://imgsrc.baidu.com/forum/pic/item/a8ec8a13632762d006deaa12a0ec08fa503dc6bf.jpg",    "fromURL":"http://tieba.baidu.com/p/1690102901",
"fromURLHost":"tieba.baidu.com",
"currentIndex":"",
"width":900,
"height":597,
"type":"jpg",
"filesize":"",
"bdSrcType":"-1",
"di":"0",
"adid":"0",
"is":"",
"simid_info":null,
"face_info":null,
"xiangshi_info":null,
"adPicId":"0",
"pi":"0",
"bdSetImgNum":0,
"bdImgnewsDate":"1970-01-01 08:00",
"fromPageTitle":"微距摄影",
"fromPageTitleEnc":"微距摄影",
"bdSourceName":"",
"bdFromPageTitlePrefix":"",
"token":""
},
{
"thumbURL":"http://img4.imgtn.bdimg.com/it/u=1193418232,3244632658&fm=23&gp=0.jpg",
"middleURL":"http://img4.imgtn.bdimg.com/it/u=1193418232,3244632658&fm=21&gp=0.jpg",
"largeTnImageUrl":"",
"hasLarge" :0,
"hoverURL":"http://img4.imgtn.bdimg.com/it/u=1193418232,3244632658&fm=23&gp=0.jpg",
"pageNum":1,
"objURL":"http://img4.duitang.com/uploads/item/201408/30/20140830185456_Eijik.jpeg",    "fromURL":"http://www.duitang.com/people/mblog/196468797/detail/",
"fromURLHost":"www.duitang.com",
"currentIndex":"",
"width":1200,
"height":800,
"type":"jpeg",
"filesize":"",
"bdSrcType":"0",
"di":"119581535480",
"adid":"0",
"is":"0,0",
"simid_info":null,
"face_info":null,
"xiangshi_info":null,
"adPicId":"0",
"pi":"0",
"bdSetImgNum":0,
"bdImgnewsDate":"1970-01-01 08:00",
"fromPageTitle":"<strong>微距摄影<\/strong>照片",
"fromPageTitleEnc":"微距摄影照片",
"bdSourceName":"",
"bdFromPageTitlePrefix":"",
"token":""
},
.........................

从上面的返回结果可以看出,JSON对象中的data域是一个数组,其中的每一项为实际的图片数据。
例如,我们可以获取data中的objURL,然后根据此地址获得实际的图片。

我们看看这部分完整的示例代码:

public class ImageFetcher {public List<GalleryItem> fetchItems() {//我们在GalleryItem中存储解析出的JSON数据List<GalleryItem> items = new ArrayList<>();try {String url = Uri.parse("http://image.baidu.com/search/index?").buildUpon().appendQueryParameter("tn", "resultjson").appendQueryParameter("word", "微距摄影").build().toString();String jsonString = HttpUtil.getUrlString(url);//将得到的返回结果分装到JSONObject中JSONObject jsonBody = new JSONObject(jsonString);//然后,解析JSONObjectparseItems(items, jsonBody);} catch (JSONException | IOException e) {e.printStackTrace();}return items;}private void parseItems(List<GalleryItem> items, JSONObject jsonBody)throws IOException, JSONException {//根据返回的JSON数据格式,我们知道“data”域对应JSONArrayJSONArray dataArray = jsonBody.getJSONArray("data");for (int i = 0; i < dataArray.length(); ++i) {JSONObject dataObject = dataArray.getJSONObject(i);GalleryItem item = new GalleryItem();//保存JSONArray中每一项的objURL,利用该Url就可以获取实际的数据item.setUrl(dataObject.getString("objURL"));items.add(item);}}
}

获取URL后的下载及解析图片的内容,在此篇博客中就不再进一步叙述了。


3、补充

上面获取JSON数据的方法实际上是不得已的“野路子”,如果百度图片修改了JSON结果的格式,那么代码也要随之修改。
一般正常情况下,应该使用云服务提供的API,然后按照API定义的JSON格式处理返回结果,例如使用Google、比应等提供的API接口。
不过为了使用云服务,必须申请对应的Api key,这就涉及到一些申请过程和收费了,具体的可以参考这些服务的说明文档。

使用云服务的好处在于:接口稳定,而且有一些便捷的方法可以使用,例如flickr提供的接口(这段代码的主要部分引用于Android权威指南):

public void fetchItems() {try {String url = Uri.parse("https://api.flickr.com/services/rest/").buildUpon()//这就是云服务便利的地方,提供了方法给客户端使用.appendQueryParameter("method", "flickr.photos.getRecent")//这里需要填写申请到的api_key.appendQueryParameter("api_key", API_KEY).appendQueryParameter("format", "json")............build().toString();String jsonString = HttpUtil.getUrlString(url);//得到结果后,按照云服务约定的方式,解析JSON对象,方法与上面的代码类似....................} catch(IOException ioe) {............}
}

4、使用GSON来简化json数据的解析

对于固定格式的json数据而言,每次都用上述方式,分析数据格式然后逐步解析比较繁琐。
幸好有现成的第三方库Gson可以使用。

Gson的使用比较简单,主要是按照Json的格式定义序列化的Bean对象。

以上面百度图片返回的结果为例:

public class Response {//每个成员与Json中的key值一致private String queryEnc;private String queryExt;private String listNum;private String displayNum;private String gsm;private String bdSearchTime;private String isNeedAsyncRequest;private String bdIsClustered;//保存Json中的data数组private List<Data> data;public String getQueryEnc() {return queryEnc;}public void setQueryEnc(String queryEnc) {this.queryEnc = queryEnc;}public String getQueryExt() {return queryExt;}public void setQueryExt(String queryExt) {this.queryExt = queryExt;}public String getListNum() {return listNum;}public void setListNum(String listNum) {this.listNum = listNum;}public String getDisplayNum() {return displayNum;}public void setDisplayNum(String displayNum) {this.displayNum = displayNum;}public String getGsm() {return gsm;}public void setGsm(String gsm) {this.gsm = gsm;}public String getBdSearchTime() {return bdSearchTime;}public void setBdSearchTime(String bdSearchTime) {this.bdSearchTime = bdSearchTime;}public String getIsNeedAsyncRequest() {return isNeedAsyncRequest;}public void setIsNeedAsyncRequest(String isNeedAsyncRequest) {this.isNeedAsyncRequest = isNeedAsyncRequest;}public String getBdIsClustered() {return bdIsClustered;}public void setBdIsClustered(String bdIsClustered) {this.bdIsClustered = bdIsClustered;}public List<Data> getData() {return data;}public void setData(List<Data> data) {this.data = data;}
}

同样,再定义一个Data对象:

public class Data {//同样,Data中的成员与Json内data的key值一致private String thumbURL;private String middleURL;private String hasLarge;private String objURL;private String fromURLHost;private String currentIndex;private String width;private String height;private String type;private String filesize;private String bdSrcType;private String di;private String adid;private String is;private String simid_info;private String face_info;private String xiangshi_ifno;private String adPicId;private String pi;private String bdSetImgNum;private String bdImgnewsDate;private String fromPageTitle;private String fromPageTitleEnc;private String bdSourceName;private String bdFromPageTitlePrefix;private String token;public String getThumbURL() {return thumbURL;}public void setThumbURL(String thumbURL) {this.thumbURL = thumbURL;}public String getMiddleURL() {return middleURL;}public void setMiddleURL(String middleURL) {this.middleURL = middleURL;}public String getHasLarge() {return hasLarge;}public void setHasLarge(String hasLarge) {this.hasLarge = hasLarge;}public String getObjURL() {return objURL;}public void setObjURL(String objURL) {this.objURL = objURL;}public String getFromURLHost() {return fromURLHost;}public void setFromURLHost(String fromURLHost) {this.fromURLHost = fromURLHost;}public String getCurrentIndex() {return currentIndex;}public void setCurrentIndex(String currentIndex) {this.currentIndex = currentIndex;}public String getWidth() {return width;}public void setWidth(String width) {this.width = width;}public String getHeight() {return height;}public void setHeight(String height) {this.height = height;}public String getType() {return type;}public void setType(String type) {this.type = type;}public String getFilesize() {return filesize;}public void setFilesize(String filesize) {this.filesize = filesize;}public String getBdSrcType() {return bdSrcType;}public void setBdSrcType(String bdSrcType) {this.bdSrcType = bdSrcType;}public String getDi() {return di;}public void setDi(String di) {this.di = di;}public String getAdid() {return adid;}public void setAdid(String adid) {this.adid = adid;}public String getIs() {return is;}public void setIs(String is) {this.is = is;}public String getSimid_info() {return simid_info;}public void setSimid_info(String simid_info) {this.simid_info = simid_info;}public String getFace_info() {return face_info;}public void setFace_info(String face_info) {this.face_info = face_info;}public String getXiangshi_ifno() {return xiangshi_ifno;}public void setXiangshi_ifno(String xiangshi_ifno) {this.xiangshi_ifno = xiangshi_ifno;}public String getAdPicId() {return adPicId;}public void setAdPicId(String adPicId) {this.adPicId = adPicId;}public String getPi() {return pi;}public void setPi(String pi) {this.pi = pi;}public String getBdSetImgNum() {return bdSetImgNum;}public void setBdSetImgNum(String bdSetImgNum) {this.bdSetImgNum = bdSetImgNum;}public String getBdImgnewsDate() {return bdImgnewsDate;}public void setBdImgnewsDate(String bdImgnewsDate) {this.bdImgnewsDate = bdImgnewsDate;}public String getFromPageTitle() {return fromPageTitle;}public void setFromPageTitle(String fromPageTitle) {this.fromPageTitle = fromPageTitle;}public String getFromPageTitleEnc() {return fromPageTitleEnc;}public void setFromPageTitleEnc(String fromPageTitleEnc) {this.fromPageTitleEnc = fromPageTitleEnc;}public String getBdSourceName() {return bdSourceName;}public void setBdSourceName(String bdSourceName) {this.bdSourceName = bdSourceName;}public String getBdFromPageTitlePrefix() {return bdFromPageTitlePrefix;}public void setBdFromPageTitlePrefix(String bdFromPageTitlePrefix) {this.bdFromPageTitlePrefix = bdFromPageTitlePrefix;}public String getToken() {return token;}public void setToken(String token) {this.token = token;}
}

Bean对象定义完毕后,就可以使用Gson了,示例如下:

public class ImageFetcher {public List<GalleryItem> fetchItems() {List<GalleryItem> items = new ArrayList<>();try {String url = Uri.parse("http://image.baidu.com/search/index?").buildUpon().appendQueryParameter("tn", "resultjson").appendQueryParameter("word", "微距摄影").build().toString();String jsonString = HttpUtil.getUrlString(url);//创建GsonGson gson = new Gson();//Gson按照Response中的定义,将字符串解析成Response对象Response response = gson.fromJson(jsonString, Response.class);parseItems(items, response);} catch (JSONException | IOException e) {e.printStackTrace();}return items;}private void parseItems(List<GalleryItem> items, Response response)throws IOException, JSONException {//然后就可以直接调用对象的接口得到需要的数据了List<Data> dataList = response.getData();for (Data data : dataList) {GalleryItem item = new GalleryItem();item.setUrl(data.getObjURL());items.add(item);}}
}

Android建立网络连接,利用JSON数据获取百度图片搜索结果及GSON的简单使用相关推荐

  1. 第十一篇 ANDROID 系统网络连接和管理机制与架构

    一  网络连接功能介绍 ANDROID 系统网络连接和管理服务由四个系统服务ConnectivityService.NetworkPolicyManagerService.NetworkManagem ...

  2. 计算机语言dial,Go语言Dial()函数:建立网络连接

    Go语言中 Dial() 函数用于创建网络连接,函数原型如下: func Dial(network, address string) (Conn, error) { var d Dialer retu ...

  3. Android判断网络连接是否可用,WiFi、移动数据是否打开等

    Android判断网络连接是否可用,WiFi.移动数据是否打开等 添加权限 <uses-permission android:name="android.permission.ACCE ...

  4. 如何利用百度图片搜索进行引流?原理是怎样的?

    究竟百度图片搜索如何运作?其实它的运作原理与搜索引擎很类似,一样会经过以下三个步骤: 爬取 Crawling 索引 Indexing 排序 Ranking 百度图片蜘蛛会先去爬取网络上各个网站的图片, ...

  5. 基于百度图片搜索的vscode插件——超级鼓励师

    简介 超级鼓励师是一款vscode插件,基于百度图片搜索服务,根据用户设置的关键字获取图片.并通过webview展示给用户.缓解程序猿/媛工作压力,给予你爱的鼓励. vscode 插件市场搜索超级鼓励 ...

  6. Python爬取百度图片搜索结果

    爬取百度图片搜索的图片,我们先需要分析其访问 URL,我们在搜索页面,比如搜索 "abc" ,打开 F12 调试,下拉结果页面页,查看网络请求,在其中我们可以找到这样一个请求 ht ...

  7. 寻找百度图片搜索接口--three

    我是怎么破解他的objurl的呢,其实怎么破解是还是百度自己告诉我的...你想啊,他为啥能在开始我看到的那个js 中显示成正常的url地址呢?为什么url中的objurl 知识编码了一下 :  /   ...

  8. python爬虫百度图片搜索_python 爬虫百度图片之列表图

    一.爬虫准备 语言:python 浏览器:google chrome 工具:request模块 首先我们在百度图片搜索页面输入需要搜索的关键词(比如:明星)页面结果如下 image.png 按F12进 ...

  9. 百度图片搜索搜出大量色情图片,原因不明

    访客Oculi同学在百度图片搜索上搜索关键字"gif"与"jpg"时发现,返回的搜索结果中出现了大量的色情图片. 不知百度一向宣称的过滤技术,在此时为何不能发挥 ...

最新文章

  1. 分享42个超棒的智能手机摄影画廊
  2. java cmd 等待输入_JAVA:调用cmd指令(支持多次手工输入)
  3. formdata传参java用对象怎么接受_Java基础4
  4. 教小学妹学算法:十大经典排序算法深度解析
  5. wxpython多线程消息传递_wxpython多线程间通信
  6. 图解TCPIP-DNS
  7. localstorage存mysql_存储localstorage
  8. php安全性怎么样,PHP网站安全性浅谈
  9. 社会工程学之《反欺骗的艺术》小结(一)
  10. 5s管理清洁活动如何推行?
  11. 【码上实战】【立体匹配系列】经典SGM:(3)代价聚合
  12. JAVA设计模式——享元模式
  13. 走近汇编理解与内核编程(楚狂人)
  14. #新技能# ps 简单抠图【持续更新】
  15. thinkadmin开源框架获取添加信息的主键id
  16. Windows10修改Users下的用户文件夹名
  17. Vue2.x动态组件的使用实现组件整合大屏展示
  18. NFT会接力Defi,成为下一个热点么?
  19. Linux基础学习Day2之基本概念及操作
  20. 使用STM32CubeMX创建工程模板

热门文章

  1. 十二不香,十三香!包邮送iPhone13一部!
  2. lxml和JsonPath的使用案例
  3. Docker基础与进阶梳理(干货满满)
  4. u大师u盘装系统win7_U盘装系统教程
  5. python 基于PHP+mysql音乐爱好者交流论坛
  6. 百度网站递交_实现网站95%收录的提交方案
  7. 火出圈的ChatGPT,如何让安全检测更智能
  8. 计算机英语videos啥意思,英语video的中文是什么意思
  9. 关于hive的那些事(下)
  10. arguments了解