Android网络与数据存储——网络编程数据处理(网络请求解析Json,解析xml)

简介: Android网络与数据存储——网络编程数据处理(网络请求解析Json,解析xml)

一.网络请求


1.URL


在真正学习网络请求之前有必要了解一下什么是URL,URL的英文全拼是Uniform Resource Locator,翻译过来为统一资源定位器,大概意思就是URL是指向互联网资源的指针。


这里说的资源可以是文件或目录,也可以是对象的引用,例如对数据库或搜索引擎的查询。


URL的组成:协议名、主机、端口和资源。即满足如下格式:

protocol://host:port/resourceName

例如 baidu的URL地址:

https://www.baidu.com

URL类提供了多个构造器用于创建URL对象,一旦获得了URL对象之后,就可以访问该URL对象对应的资源了。


2.Http网络请求

Android中的Http网络请求有两种方式:


HttpURLConnection

HttpClient(已不推荐使用)

既然HttpClient已被弃用,那就用HttpURLConnection。


HttpURLConnection继承了URLConnection,可用于向指定网站发送GET请求、POST请求。提供了一下方法:


HttpURLConnection openConnection():返回一个HttpURLConnection对象,表示到URL所引用的远程对象的连接。

int getResponseCode():获取服务器的响应代码。例如:200表示服务器成功响应,404表示没响应。

String getResponseMessage():获取服务器的响应消息。

String getRequestMethod():获取发送请求的方法。

void setRequestMethod():设置发送请求的方法。

void setConnectTimeout():设置连接延迟时间。

void setReadTimeout():设置读取延迟时间。

下边写一个请求百度API获取全国城市的方法来使用上面提到的方法。代码如下:

public void requestCityData(final String urlString) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    URL url = new URL(urlString);
                    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                    connection.setRequestMethod("GET");
                    connection.setConnectTimeout(8000);
                    connection.setReadTimeout(8000);
                    connection.connect();
                    if (connection.getResponseCode() == 200) {
                        InputStream inputStream = connection.getInputStream();
                        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
                        String line;
                        StringBuilder builder = new StringBuilder();
                        while ((line = reader.readLine()) != null) {
                            builder.append(line);
                        }
                        reader.close();
                        String result = builder.toString();
                        Message msg = new Message();
                        msg.what = 0;
                        msg.obj = result;
                        handler.sendMessage(msg);
                    }
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
}

从以上代码可以看出请求网络数据的方法可以分为以下步骤:


创建URL对象url。

通过url.openConnection()获取HttpURLConnection对象connection。

设置请求方式、连接延迟、读取延迟、连接。

通过connection.getResponseCode()获取响应码来判断是否连接成功。

如果连接成功,接下来的读取文件和Java的读文件操作一样。

由于请求网络数据的操作属于耗时操作,所以应该把整个请求操作放在了子线程(处理异步数据有两种方式:handler和AsyncTask,这里用handler进行实现,下一篇中的利用多线程下载会用AsyncTask),最后把请求到的数据通过handler.sendMessage()方法发送到主线程,在handler中的handleMessage()方法中对请求到的数据进行处理。handler代码如下:

Handler handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case 0: String cityData = msg.obj.toString(); Log.d("CityActivity", cityData); break; } } };


这里的handler只是简单的打印了一下请求到的数据。


到目前为止,还不算请求完成,因为这里用到了网络,要想获取网络上的数据,该应用必须有请求网络的权限,在AndroidManifest.xml中加入网络权限即可。

<uses-permission android:name="android.permission.INTERNET" />


二.解析xml


如果请求到的数据为xml类型的,就需要把xml类型的数据解析成我们想要的类型或从xml类型的数据中解析出我们想要的数据。


解析xml类型数据有两种方式:


SAX:基于事件驱动的解析(解析器+事件处理器),较复杂。

PULL

DOM:基于文件流。

SAX、PULL是一个标签一个标签读,分段加载;DOM是整个文件读取出来,然后加载。


1.SAX


利用SAX解析如下xml中的id、url以及item text。

<?xml version="1.0" encoding="utf-8"?>
<web>
    <item id = "0" url = "http://www.baidu.com" >百度</item>
    <item id = "1" url = "http://www.google.com" >谷歌</item>
    <item id = "2" url = "http://www.sohu.com" >搜狐</item>
</web>

先新建一个SAXParseHandler类继承自DefaultHandler,并实现startDocument()、startElement()、characters()、endElement()、endDocument()这五个方法。

public class SAXParseHandler extends DefaultHandler {
    private List<WebURL> mWebURLs;
    private WebURL mWebURL;
    private boolean state = false;
    @Override
    public void startDocument() throws SAXException {
        mWebURLs = new ArrayList<>();
    }
    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        mWebURL = new WebURL();
        if (TextUtils.equals(localName, "item")){
            for (int i = 0; i < attributes.getLength(); i++) {
                if (TextUtils.equals(attributes.getLocalName(i), "id")){
                    mWebURL.setmID(Integer.parseInt(attributes.getValue(i)));
                }else if (TextUtils.equals(attributes.getLocalName(i), "url")){
                    mWebURL.setmUrl(attributes.getValue(i));
                }
            }
            state = true;
        }
    }
    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        String content = String.valueOf(ch, start, length);
        if (state) {
            mWebURL.setmContent(content);
            state = false;
        }
    }
    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        if (TextUtils.equals(localName, "item")){
            mWebURLs.add(mWebURL);
        }
    }
    @Override
    public void endDocument() throws SAXException {
    }
}

以上代码中startDocument()表示解析到最外层的标签,进行一些初始化操作,startElement()表示解析到子标签,通过attributes来获取该标签的属性id和url,characters()表示子标签开始标签和结束标签中间的内容,在这里通过转换ch可以获取到,endElement()表示结束子标签,在这个方法中将获取到的信息进行保存,endDocument()表示解析结束。


SAXParseHandler类将xml的每一个标签进行了遍历,接下来就是通过SAX解析器进行解析了。解析代码如下:

private void testSAXParse() throws ParserConfigurationException, SAXException, IOException {
        //定义一个factory API,能够配置和获取一个SAX解析器去解析xml
        //SAXParserFactory.newInstance();返回Android的接口SAXParserFactory,不像其他Java接口,该方法不能产生系统属性
        SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();//属性文件或服务API
        //定义一个API包裹XMLReader实现类
        SAXParser saxParser = saxParserFactory.newSAXParser();
        //读一个xml文档的接口,用于回调
        XMLReader xmlReader = saxParser.getXMLReader();
        saxParseHandler = new SAXParseHandler();
        //将saxParseHandler的实例设置到XMLReader中
        xmlReader.setContentHandler(saxParseHandler);
        InputStream inputStream = getResources().openRawResource(R.raw.test);
        InputSource inputSource = new InputSource(inputStream);
        //开始执行解析
        xmlReader.parse(inputSource);
    }

以上代码中的注释写的很详细,就不在啰嗦了。



三.解析Json


Android中解析Json的类有JSONObject和JSONArray。

格式化Json数据的网址:jsonlint.com

开源库:对开源库还未进行研究,待研究了回来补充...

GSON

fastJson


通过JSONObject和JSONArray来对下面一段Json数据进行解析。

{city_info: [ 
{city: "北京", cnty: "中国", id: "CN101010100", lat: "39.904000", lon: "116.391000", prov: "直辖市" }, ... 
] }

写一个方法对以上Json数据进行解析,代码如下:

public List<CityInfo> parseCityData(String cityData) {
        List<CityInfo> cityInfos = new ArrayList<>();
        try {
            JSONObject jsonObject = new JSONObject(cityData);
            JSONArray jsonArray = jsonObject.getJSONArray("city_info");
            for (int i = 0; i < jsonArray.length(); i++) {
                JSONObject cityObject = (JSONObject) jsonArray.get(i);
                String city = cityObject.getString("city");
                String prov = cityObject.getString("prov");
                CityInfo cityInfo = new CityInfo(city, prov);
                cityInfos.add(cityInfo);
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return cityInfos;
}

通过new JSONObject()获取整个JSONObject对象,然后利用getJSONArray()获取city_info对应的Json数组,然后再通过Json数组的get方法获取数组中的每一个JSONObject对象,通过关键字获取我们想要的数据,最后将数据存入列表。整个Json数据解析完毕。


四.网络状态处理


网络状态处理:可以判断是否连接网络,还可以区分移动网络流量还是WiFi网络流量

ConnectivityManager

NetworkInfo


五.扩展


  1. 下载电影、音乐的本质?
    网络请求
  2. 断点下载
    记录http的Head,下载时间,下载了哪些东西。
  3. 常用网络开源库
  • android-async-http
  • volley
  • OKHttp
  • Retrofit

4、封装请求及通用设置

  • 封装能用Header
  • 请求参数封装

5、封装结果处理

  • 能用错误码处理
  • 数据转换校验

6、拦截请求设置及代理

  • Fiddler(Windows)
  • Charles(Mac)
  • wifi设置代理

7、技巧

  • Postman查询API
  • Restful API
相关文章
|
API 数据处理 Android开发
Android网络请求演变:从Retrofit到Flow的转变过程。
通过这个比喻,我们解释了 Android 网络请求从 Retrofit 到 Flow 的转变过程。这不仅是技术升级的体现,更是反映出开发者在面对并发编程问题时,持续探索和迭求更好地解决方案的精神。未来,还会有更多新的技术和工具出现,我们期待一同 witness 这一切的发展。
559 36
|
数据采集 JSON 数据可视化
JSON数据解析实战:从嵌套结构到结构化表格
在信息爆炸的时代,从杂乱数据中提取精准知识图谱是数据侦探的挑战。本文以Google Scholar为例,解析嵌套JSON数据,提取文献信息并转换为结构化表格,通过Graphviz制作技术关系图谱,揭示文献间的隐秘联系。代码涵盖代理IP、请求头设置、JSON解析及可视化,提供完整实战案例。
864 4
JSON数据解析实战:从嵌套结构到结构化表格
|
XML JavaScript Android开发
【Android】网络技术知识总结之WebView,HttpURLConnection,OKHttp,XML的pull解析方式
本文总结了Android中几种常用的网络技术,包括WebView、HttpURLConnection、OKHttp和XML的Pull解析方式。每种技术都有其独特的特点和适用场景。理解并熟练运用这些技术,可以帮助开发者构建高效、可靠的网络应用程序。通过示例代码和详细解释,本文为开发者提供了实用的参考和指导。
603 15
|
Web App开发 缓存 JavaScript
Android网络小说阅读器的实现
小说阅读Demo,。此Demo使用Jsoup解析HTML,实现小说数据抓取(数据源自网络),并包含自定义View、六章小说缓存等功能,但未实现下载。项目还包括屏幕适配、字体设置等,借助第三方框架完成优化。以下是主页、详情页、阅读页等界面展示。
417 0
|
JSON 前端开发 搜索推荐
关于商品详情 API 接口 JSON 格式返回数据解析的示例
本文介绍商品详情API接口返回的JSON数据解析。最外层为`product`对象,包含商品基本信息(如id、name、price)、分类信息(category)、图片(images)、属性(attributes)、用户评价(reviews)、库存(stock)和卖家信息(seller)。每个字段详细描述了商品的不同方面,帮助开发者准确提取和展示数据。具体结构和字段含义需结合实际业务需求和API文档理解。
|
JavaScript 算法 前端开发
JS数组操作方法全景图,全网最全构建完整知识网络!js数组操作方法全集(实现筛选转换、随机排序洗牌算法、复杂数据处理统计等情景详解,附大量源码和易错点解析)
这些方法提供了对数组的全面操作,包括搜索、遍历、转换和聚合等。通过分为原地操作方法、非原地操作方法和其他方法便于您理解和记忆,并熟悉他们各自的使用方法与使用范围。详细的案例与进阶使用,方便您理解数组操作的底层原理。链式调用的几个案例,让您玩转数组操作。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
JSON 小程序 UED
微信小程序 app.json 配置文件解析与应用
本文介绍了微信小程序中 `app.json` 配置文件的详细
2525 12
|
JSON 缓存 API
解析电商商品详情API接口系列,json数据示例参考
电商商品详情API接口是电商平台的重要组成部分,提供了商品的详细信息,支持用户进行商品浏览和购买决策。通过合理的API设计和优化,可以提升系统性能和用户体验。希望本文的解析和示例能够为开发者提供参考,帮助构建高效、可靠的电商系统。
729 12
|
JSON JavaScript 前端开发
一次采集JSON解析错误的修复
两段采集来的JSON格式数据存在格式问题,直接使用PHP的`json_decode`会报错。解决思路包括:1) 手动格式化并逐行排查错误;2) 使用PHP-V8JS扩展在JavaScript环境中解析。具体方案一是通过正则表达式和字符串替换修复格式,方案二是利用V8Js引擎执行JS代码并返回JSON字符串,最终实现正确解析。 简介: 两段采集的JSON数据因掺杂JavaScript代码导致PHP解析失败。解决方案包括手动格式化修复和使用PHP-V8JS扩展在JavaScript环境中解析,确保JSON数据能被正确处理。
|
设计模式 存储 安全
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
结构型模式描述如何将类或对象按某种布局组成更大的结构。它分为类结构型模式和对象结构型模式,前者采用继承机制来组织接口和类,后者釆用组合或聚合来组合对象。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象结构型模式比类结构型模式具有更大的灵活性。 结构型模式分为以下 7 种: • 代理模式 • 适配器模式 • 装饰者模式 • 桥接模式 • 外观模式 • 组合模式 • 享元模式
923 140
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析

推荐镜像

更多
  • DNS