【Android前端】Bing每日图片列表应用制作记录——3.获取网络数据(上)
来源:互联网 发布:如何更改数据库所有者 编辑:程序博客网 时间:2024/05/22 17:25
这次也是因为一些变故拖了很久才更新,但是生活总是要继续。
第三篇:获取网络数据(上)
上次说过我们的预期效果是从网络加载数据,那么怎么对现有代码进行改造呢?
首先我们回到DataResource获取数据的函数getData()里:
public List<Map<String,Object>> getData() { for(int i=1;i<=5;i++){ map=new HashMap<>(); map.put("pic",R.mipmap.test); map.put("text","这里应该是内容"); map.put("time","这里应该有时间"); list.add(map); } return list; }可以看到现在返回的List中的内容是我们加入的固定内容,那么应该修改的就是这部分了。那么下一个问题是:数据从哪里来?
第一部分:API
好了我们看看标题——这次用的是Bing每日图片的API,Url如下:http://www.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1&mkt=zh-CN。
试试直接在浏览器里访问:
得到的这串字符就是我们的目标了,这是JSON字符串,解释的话这里贴一段百科:
JSON(JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式。它基于 ECMAScript (w3c制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
总的来说,JSON字符串可以用文本来“存储和表达数据”,这种格式目前也是非常常见的,具体的大家可以看一看这一篇博文。
回到API本体,不难看出,字符串中的startdate,url和copyright三个变量的数据就是我们需要的,我们的目标也就是把这三个变量的值放进HashMap再添加到List最终传给Adapter以展示出来。
PS:关于这个API稍微说一说参,n是数据条数,mkt是地区,但是很不幸的是这个API存在限制,一次最多返回8个image成员,当然已经够我们练习用了。
第二部分:HttpUrlConnection
Android中发送http网络请求是很常见的,在Android API Level 9(Android 2.2)之前使用的是DefaultHttpClient类发送http请求。DefaultHttpClient是Apache用于发送http请求的客户端,API支持强大性能完善,但是由于其太过复杂,Android团队在保持向后兼容的情况下,很难对DefaultHttpClient进行增强。为此Android团队自己实现了一个发送http请求的客户端类——–HttpURLConnection。相比于原来的DefaultHttpClient,HttpURLConnection比较轻量级,虽然功能没有DefaultHttpClient那么强大,但是能够满足大部分的需求,所以Android推荐使用HttpURLConnection代替DefaultHttpClient,并不强制使用HttpURLConnection。但从Android API Level 23(Android 6.0)开始,不能再在Android中使用DefaultHttpClient,强制使用HttpURLConnection。
这次我们就用HttpUrlConnection来实现请求网络数据,Http请求分为GET请求和POST请求,因为这次的需求很简单,所以只用get请求就可以了。
使用前别忘了在AndroidManifest.xml中申请网络使用权限:
<uses-permission android:name="android.permission.INTERNET" />
一个完整的http请求需要经历两个过程:客户端发送请求到服务器,然后服务器将结果返回给客户端,来直接上代码:
try{ String path = "http://www.bing.com/HPImageArchive.aspx?format=js&idx=0&n=5&mkt=zh-CN"; URL url = new URL(path); HttpURLConnection urlConn = (HttpURLConnection) url.openConnection(); urlConn.setConnectTimeout(5000); urlConn.connect(); if (urlConn.getResponseCode() == 200) { //处理数据 Log.i(TAG, "请求成功"); } else { Log.i(TAG, "请求失败"); } urlConn.disconnect(); }catch (Exception e){ e.printStackTrace(); }如上面一段代码所示,我们建立了一个新的HttpURLConnection对象,并用它连接了API相关的url,最后返回连接结果。细看代码,而if判断中的urlConn.getResponseCode() == 200正是代表连接成功(大家应该都见过404吧,关于返回码具体可以参照这一篇)。
这一段代码已经可以搭建一个简单的http请求了,但是很明显处理数据的部分我们还没有做,不过实现起来也很简单:HttpURLConnection类自带getInputStream()函数。但是这样并不够,因为我们还需要把InputStream格式的数据变成可处理的String类型,所以我们额外实现一个函数readStream():
private String readStream(InputStream inputStream) throws IOException{ ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len; while((len=inputStream.read(buffer))!=-1){ outputStream.write(buffer,0,len); outputStream.flush(); } outputStream.close(); inputStream.close(); return outputStream.toString(); }简单来讲就是先将输入流变成ByteArrayOutputStream,再通过toString()方法得到String类型的结果,顺带一提get请求方式最多也只能得到2048字节大小的数据,所以不用担心。当然了还得在if段中调用:
if (urlConn.getResponseCode() == 200) { String data = readStream(urlConn.getInputStream()); Log.i(TAG, "请求成功"); Log.i(TAG, data); } else { Log.i(TAG, "请求失败"); }
这样简单的请求数据过程算是实现了,但是还有一个更大的问题:这个部分放在哪?
第三部分:AsyncTask
网络请求是非常忌讳放在主线程运行的,不仅会堵塞进程,造成的界面僵死更会让用户十分恼火,这里用的就是一个很简单的办法:AsyncTask。AsyncTask,也就是异步任务,是Android提供的轻量级的异步类,我们可以直接继承AsyncTask以在类中实现异步操作。实际使用中我们最少要重写以下这两个方法:doInBackground(Params…) 后台执行,比较耗时的操作都可以放在这里,不过注意这里不能直接操作UI,此外在执行过程中可以调用publicProgress(Progress…)来更新任务的进度;而onPostExecute(Result) 相当于Handler 处理UI的方式,在这里面可以使用在doInBackground 得到的结果处理操作UI。 此方法在主线程执行,任务执行的结果作为此方法的参数返回。
还是直接用代码来说明吧,我们新建立一个DataAsyncTask类继承自AsyncTask:
package com.xugino.bingpicanother;import android.os.AsyncTask;import android.util.Log;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.InputStream;import java.net.HttpURLConnection;import java.net.URL;import java.util.ArrayList;import java.util.List;import java.util.Map;import static android.content.ContentValues.TAG;class DataAsyncTask extends AsyncTask<Integer,Void,Void> { DataAsyncTask(){ super(); } @Override protected Void doInBackground(Integer... param) { try{ String path = "http://www.bing.com/HPImageArchive.aspx?format=js&idx=0&n=5&mkt=zh-CN"; URL url = new URL(path); HttpURLConnection urlConn = (HttpURLConnection) url.openConnection(); urlConn.setConnectTimeout(5000); urlConn.connect(); if (urlConn.getResponseCode() == 200) { String data = readStream(urlConn.getInputStream()); Log.i(TAG, "请求成功"); Log.i(TAG, data); } else { Log.i(TAG, "请求失败"); } urlConn.disconnect(); }catch (Exception e){ e.printStackTrace(); } return null; } private String readStream(InputStream inputStream) throws IOException{ ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len; while((len=inputStream.read(buffer))!=-1){ outputStream.write(buffer,0,len); outputStream.flush(); } outputStream.close(); inputStream.close(); return outputStream.toString(); }}
然后在getData()中调用:
package com.xugino.bingpicanother;import java.util.ArrayList;import java.util.List;import java.util.Map;public class DataResource { private List<Map<String,Object>> list; private DataAsyncTask myTask; public DataResource(){ list=new ArrayList<>(); } public List<Map<String,Object>> getData() { try{ myTask = new DataAsyncTask(); myTask.execute(0); }catch (Exception e){ e.printStackTrace(); } return list; }}然后运行看看:
毫无疑问这部分很成功,但是你再看看我们的App界面——一片空白,我们现在得到的只是json字符串而已,真正要把它转换成真正的数据显示出来还要经过更多的处理。
下一篇文章我们会使用Google家的gson来解析json字符串,学会使用这些外部依赖也是入门的一部分。
阅读全文
0 0
- 【Android前端】Bing每日图片列表应用制作记录——3.获取网络数据(上)
- 【Android前端】Bing每日图片列表应用制作记录——4.获取网络数据(下)
- 【Android前端】Bing每日图片列表应用制作记录——2.列表的实现
- 【Android前端】Bing每日图片列表应用制作记录——1.从零开始
- Bing获取-获取Bing每日图片
- php获取bing每日图片
- 自学python之获取bing每日图片
- 【android初级】之Android之从网络上获取数据(图片,网页,xml,json等)
- android 从网络上获取数据(图片,网页,xml,json等)
- 动态获取Bing每日壁纸
- Android获取网络图片、获取服务器数据
- android—获取网络数据
- android获取网络上的图片
- Android 获取网络上的图片
- Android 如何获取网络上的图片
- android 从网络上获取图片
- 【android基础】之Android获取网络上的图片结合ImageView的简单应用
- android_学习—获取网络数据(图片,html)
- 机器学习资料
- java 基本数据类型及自动类型提升
- Stack Overflow 2017 开发者调查报告发布
- oracle 11g+plsql安装与配置(小白实现)
- JAVA设计模式之单例模式
- 【Android前端】Bing每日图片列表应用制作记录——3.获取网络数据(上)
- 4.26 leetcode -26 sqrtx
- 天平难题 UVa 1354
- android studio中svn的使用
- Android
- Android Gradle使用总结
- java程序员面试宝典
- 把excel导入到数据库中
- X光、CT、核磁、B超的区别,讲得太到位了