Android网络部分-----网络数据请求、解析

简介: Android网络部分-----网络数据请求、解析

一.网络知识简介

      1. 网络操作是Android开发中很重要的一部分,我们在移动端开发的app如何不断地向服务器发送请求并接受服务器发送来的json格式的字符串,通过json解析技术把指定的内容展示在指定的控件上面。

      2. 首先客户端在发送请求之前是需要TCP或者UDP来基于三次握手技术和服务端建立连接,然后通过http协议这种应用技术发送请求和接收响应,http提供了封装或者显示数据的具体形式,Socket提供了网络通信的能力。

      3. 网络请求方式:GET和POST

GET 主要作用是从服务器获取数据,方式是将参数拼接在url后面,前端直接可以看到,传输层角度来说不是很安全,但是本质层来说,因为get是获取数据不会对服务器数据修改,所以安全。

POST主要作用是给服务器提交数据,方式是将数据放在数据包发送,看不到的,传输层角度来说比较安全,但是本质层来说,因为post是操作是对服务器数据修改,所以不是很安全。

二:get请求数据(原生方法)

public class IndexActivity extends AppCompatActivity implements View.OnClickListener {
    private String result;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
 
    @Override
    public void onClick(View v) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                URL url = null;
                try {
                    //获取URL实例
                    url = new URL("xxxx请求地址");
                    //获取链接对象
                    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                    //设置请求方法
                    connection.setRequestMethod("GET");
                    //设置请求超时时间
                    connection.setConnectTimeout(30 * 1000);
                    connection.setRequestProperty("Content-type", "application/json");
                    connection.setRequestProperty("Charset", "UTF-8");
                    connection.setRequestProperty("Accept-Charset", "UTF-8");
                    //发起连接
                    connection.connect();
                    int responseCode = connection.getResponseCode();
                    String message = connection.getResponseMessage();
                    if (responseCode == HttpURLConnection.HTTP_OK) {
                        //获取inputStream流
                        InputStream inputStream = connection.getInputStream();
                        //将得到的inputStream流转成字符串
                        result = streamToString(inputStream);
                        Log.e("结果是", result);
                        final TextView textView = findViewById(R.id.result);
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                result=decode(result);
                                textView.setText(result);
                            }
                        });
                       /* textView.post(new Runnable() {
                            @Override
                            public void run() {
                                textView.setText(result);
                            }
                        });*/
                    }
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
 
    }
 
    /**
     * inputStream转为String
     *
     * @param in 要传入的流对象
     * @return 结果字符串
     */
    private String streamToString(InputStream in) {
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();//定义一个输出管道
            byte[] buffer = new byte[1024];
            int len;
            while ((len = in.read()) != -1) {//写入管道
                baos.write(buffer, 0, len);
            }
            baos.close();
            in.close();
            byte[] bytesArray = baos.toByteArray();//管道转为字节数组
            return new String(bytesArray);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
 
    /**
     * 将Unicode字符转换为UTF-8类型字符串
     */
    public static String decode(String unicodeStr) {
        if (unicodeStr == null) {
            return null;
        }
        StringBuilder retBuf = new StringBuilder();
        int maxLoop = unicodeStr.length();
        for (int i = 0; i < maxLoop; i++) {
            if (unicodeStr.charAt(i) == '\\') {
                if ((i < maxLoop - 5)
                        && ((unicodeStr.charAt(i + 1) == 'u') || (unicodeStr
                        .charAt(i + 1) == 'U')))
                    try {
                        retBuf.append((char) Integer.parseInt(unicodeStr.substring(i + 2, i + 6), 16));
                        i += 5;
                    } catch (NumberFormatException localNumberFormatException) {
                        retBuf.append(unicodeStr.charAt(i));
                    }
                else {
                    retBuf.append(unicodeStr.charAt(i));
                }
            } else {
                retBuf.append(unicodeStr.charAt(i));
            }
        }
        return retBuf.toString();
    }
}

重点:

1.因为我们请求网络数据会有数据等待,这时候如果我们在主线程中操作,就会出现卡死主线程异常,所以对于数据请求的操作我们要放在一个子线程中让其运行

2.在涉及到请求网络的时候在mainifest配置文件中需要声明网络权限

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

3.只有在主线程中才能更新ui,子线程中不能操作ui,可以通过Handler更新UI,后面或介绍这种方法,这里还有两种处理方法就是

代码中的

runOnUiThread(new Runnable() {
    @Override
    public void run() {
        textView.setText(result);
    }
});

把ui更新操作放到主线程中运行

另外就是TextView的post方法可以直接将操作更新到主线程中进行

textView.post(new Runnable() {
    @Override
    public void run() {
        textView.setText(result);
    }
});

4.在Android9.0中对http的请求进行了限制,不能访问,我们需要在res中创建一个xml/network-security-config文件

增加cleartextTrafficPermitted属性,如下

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config cleartextTrafficPermitted = "true"/>
</network-security-config>

添加到安全配置文件mainifest.xml中

上面这个限制只有在9.0中并且

targetSdkVersion 是29才会发生

三:post请求

public void onClick(View v) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    URL url = null;
                    try {
                        //获取URL实例
                        url = new URL("xxxx请求地址,不带有参数");
                        //获取链接对象
                        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                        //设置请求方法
                        connection.setRequestMethod("POST");
                        //设置请求超时时间
                        connection.setConnectTimeout(30 * 1000);
                        connection.setRequestProperty("Content-type", "application/json");
                        connection.setRequestProperty("Charset", "UTF-8");
                        connection.setRequestProperty("Accept-Charset", "UTF-8");
                        connection.setDoOutput(true);
                        connection.setDoInput(true);
                        //不用缓存
                        connection.setUseCaches(false);
                        //发起连接
                        connection.connect();
                        String data = "username=" + URLEncoder.encode("123", "UTF-8") + "123";/*有编码问题的的也可以处理*/
                        OutputStream outputStream = connection.getOutputStream();
                        outputStream.write(data.getBytes());
                        outputStream.flush();
                        outputStream.close();
                        int responseCode = connection.getResponseCode();
                        String message = connection.getResponseMessage();
                        if (responseCode == HttpURLConnection.HTTP_OK) {
                            //获取inputStream流
                            InputStream inputStream = connection.getInputStream();
                            //将得到的inputStream流转成字符串
                            result = streamToString(inputStream);
                            Log.e("结果是", result);
                            final TextView textView = findViewById(R.id.result);
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    result = decode(result);
                                    textView.setText(result);
                                }
                            });
                   /* textView.post(new Runnable() {
                        @Override
                        public void run() {
                            textView.setText(result);
                        }
                    });*/
                        }
                    } catch (MalformedURLException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
}

上面的get和post都是通过原生实现的,实际生产场景中往往使用第三方库

四:数据解析

我们通过上面的get或者post方法从网络拿到数据之后,如何把得到的json字符串解析呢?

解析json数据主要两种方法,第一种使用JSONObject解析json数据,第二种使用第三方库解析,比如谷歌提供的GSON解析JSON数据,这里演示JSONObject解析json数据

用于测试的json数据如下

{
  "status": 1,
  "data": [{
      "id": 1,
      "name": "abc"
    },
    {
      "id": 2,
      "name": "123"
    }
  ],
  "msg": "成功"
}

在json数据中每一个{}代表一个JSONObject即json对象,每一个[ ]就是一个JSONArray即json数组,所以案例数据就是一个json对象包含了一个json数组,这个json数组里面有两个json对象

我们定义对应的实体类(set、get方法省)

//最外面的json对象
public class Result {
    private int status;
    //json数组
    private List<Person> personList;
    //json数组里面的对象
    private static class Person{
        private int id;
        private String name;
    }
}

解析java代码

 public void jsonToPo(String resultJson) throws JSONException {
        JSONObject resultObject = new JSONObject(resultJson);
        int status = resultObject.getInt("status");
        JSONArray jsonArray = resultObject.getJSONArray("data");
        Result result = new Result();
        List<Result.Person> personList = new ArrayList<>();
        result.setStatus(status);
        if (jsonArray != null && jsonArray.length() > 0) {
            for (int i = 0; i < jsonArray.length(); i++) {
                //遍历每一个json对象
                JSONObject jsonObject = (JSONObject) jsonArray.get(i);
                int id  = jsonObject.getInt("id");
                String name = jsonObject.getString("name");
                Result.Person person = new Result.Person();
                person.setId(id);
                person.setName(name);
                //添加到list中
                personList.add(person);
            }
            result.setPersonList(personList);
        }
    }

更多内容关注微信公众号 java一号

文章首发地址  www.javayihao.top


相关文章
|
6月前
|
机器学习/深度学习 人工智能 算法
【基于TTNRBO优化DBN回归预测】基于瞬态三角牛顿-拉夫逊优化算法(TTNRBO)优化深度信念网络(DBN)数据回归预测研究(Matlab代码实现)
【基于TTNRBO优化DBN回归预测】基于瞬态三角牛顿-拉夫逊优化算法(TTNRBO)优化深度信念网络(DBN)数据回归预测研究(Matlab代码实现)
266 0
|
7月前
|
机器学习/深度学习 算法 调度
14种智能算法优化BP神经网络(14种方法)实现数据预测分类研究(Matlab代码实现)
14种智能算法优化BP神经网络(14种方法)实现数据预测分类研究(Matlab代码实现)
526 0
|
7月前
|
机器学习/深度学习 数据采集 运维
改进的遗传算法优化的BP神经网络用于电厂数据的异常检测和故障诊断
改进的遗传算法优化的BP神经网络用于电厂数据的异常检测和故障诊断
|
8月前
|
机器学习/深度学习 数据采集 传感器
【故障诊断】基于matlab BP神经网络电机数据特征提取与故障诊断研究(Matlab代码实现)
【故障诊断】基于matlab BP神经网络电机数据特征提取与故障诊断研究(Matlab代码实现)
261 0
|
8月前
|
XML JSON JavaScript
从解决跨域CSOR衍生知识 Network 网络请求深度解析:从快递系统到请求王国-优雅草卓伊凡
从解决跨域CSOR衍生知识 Network 网络请求深度解析:从快递系统到请求王国-优雅草卓伊凡
185 0
从解决跨域CSOR衍生知识 Network 网络请求深度解析:从快递系统到请求王国-优雅草卓伊凡
|
9月前
|
数据采集 存储 算法
MyEMS 开源能源管理系统:基于 4G 无线传感网络的能源数据闭环管理方案
MyEMS 是开源能源管理领域的标杆解决方案,采用 Python、Django 与 React 技术栈,具备模块化架构与跨平台兼容性。系统涵盖能源数据治理、设备管理、工单流转与智能控制四大核心功能,结合高精度 4G 无线计量仪表,实现高效数据采集与边缘计算。方案部署灵活、安全性高,助力企业实现能源数字化与碳减排目标。
291 0
|
9月前
|
安全 数据库 Android开发
在Android开发中实现两个Intent跳转及数据交换的方法
总结上述内容,在Android开发中,Intent不仅是活动跳转的桥梁,也是两个活动之间进行数据交换的媒介。运用Intent传递数据时需注意数据类型、传输大小限制以及安全性问题的处理,以确保应用的健壯性和安全性。
588 11
|
9月前
|
存储 监控 算法
基于 Python 跳表算法的局域网网络监控软件动态数据索引优化策略研究
局域网网络监控软件需高效处理终端行为数据,跳表作为一种基于概率平衡的动态数据结构,具备高效的插入、删除与查询性能(平均时间复杂度为O(log n)),适用于高频数据写入和随机查询场景。本文深入解析跳表原理,探讨其在局域网监控中的适配性,并提供基于Python的完整实现方案,优化终端会话管理,提升系统响应性能。
228 4
|
10月前
|
开发者
鸿蒙仓颉语言开发教程:网络请求和数据解析
本文介绍了在仓颉开发语言中实现网络请求的方法,以购物应用的分类列表为例,详细讲解了从权限配置、发起请求到数据解析的全过程。通过示例代码,帮助开发者快速掌握如何在网络请求中处理数据并展示到页面上,减少开发中的摸索成本。
鸿蒙仓颉语言开发教程:网络请求和数据解析
|
10月前
|
Python
LBA-ECO CD-32 通量塔网络数据汇编,巴西亚马逊:1999-2006,V2
该数据集汇集了1999年至2006年间巴西亚马逊地区九座观测塔的碳和能量通量、气象、辐射等多类数据,涵盖小时至月度时间步长。作为第二版汇编,数据经过协调与质量控制,扩展了第一版内容,并新增生态系统呼吸等相关计算数据,支持综合研究与模型合成。数据以36个制表符分隔文本文件形式提供,配套PDF说明文件,适用于生态与气候研究。引用来源为Restrepo-Coupe等人(2021)。
440 1

热门文章

最新文章

推荐镜像

更多