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


相关文章
|
21天前
|
数据采集 监控 API
告别手动埋点!Android 无侵入式数据采集方案深度解析
传统的Android应用监控方案需要开发者在代码中手动添加埋点,不仅侵入性强、工作量大,还难以维护。本文深入探讨了基于字节码插桩技术的无侵入式数据采集方案,通过Gradle插件 + AGP API + ASM的技术组合,实现对应用性能、用户行为、网络请求等全方位监控,真正做到零侵入、易集成、高稳定。
370 32
|
1月前
|
机器学习/深度学习 PyTorch TensorFlow
卷积神经网络深度解析:从基础原理到实战应用的完整指南
蒋星熠Jaxonic,深度学习探索者。深耕TensorFlow与PyTorch,分享框架对比、性能优化与实战经验,助力技术进阶。
|
6月前
|
人工智能 监控 安全
NTP网络子钟的技术架构与行业应用解析
在数字化与智能化时代,时间同步精度至关重要。西安同步电子科技有限公司专注时间频率领域,以“同步天下”品牌提供可靠解决方案。其明星产品SYN6109型NTP网络子钟基于网络时间协议,实现高精度时间同步,广泛应用于考场、医院、智慧场景等领域。公司坚持技术创新,产品通过权威认证,未来将结合5G、物联网等技术推动行业进步,引领精准时间管理新时代。
|
2月前
|
机器学习/深度学习 人工智能 算法
卷积神经网络深度解析:从基础原理到实战应用的完整指南
蒋星熠Jaxonic带你深入卷积神经网络(CNN)核心技术,从生物启发到数学原理,详解ResNet、注意力机制与模型优化,探索视觉智能的演进之路。
340 11
|
2月前
|
安全 网络性能优化 网络虚拟化
网络交换机分类与功能解析
接入交换机(ASW)连接终端设备,提供高密度端口与基础安全策略;二层交换机(LSW)基于MAC地址转发数据,构成局域网基础;汇聚交换机(DSW)聚合流量并实施VLAN路由、QoS等高级策略;核心交换机(CSW)作为网络骨干,具备高性能、高可靠性的高速转发能力;中间交换机(ISW)可指汇聚层设备或刀片服务器内交换模块。典型流量路径为:终端→ASW→DSW/ISW→CSW,分层架构提升网络扩展性与管理效率。(238字)
685 0
|
3月前
|
XML JSON JavaScript
从解决跨域CSOR衍生知识 Network 网络请求深度解析:从快递系统到请求王国-优雅草卓伊凡
从解决跨域CSOR衍生知识 Network 网络请求深度解析:从快递系统到请求王国-优雅草卓伊凡
108 0
从解决跨域CSOR衍生知识 Network 网络请求深度解析:从快递系统到请求王国-优雅草卓伊凡
|
4月前
|
安全 数据库 Android开发
在Android开发中实现两个Intent跳转及数据交换的方法
总结上述内容,在Android开发中,Intent不仅是活动跳转的桥梁,也是两个活动之间进行数据交换的媒介。运用Intent传递数据时需注意数据类型、传输大小限制以及安全性问题的处理,以确保应用的健壯性和安全性。
317 11
|
5月前
|
开发者
鸿蒙仓颉语言开发教程:网络请求和数据解析
本文介绍了在仓颉开发语言中实现网络请求的方法,以购物应用的分类列表为例,详细讲解了从权限配置、发起请求到数据解析的全过程。通过示例代码,帮助开发者快速掌握如何在网络请求中处理数据并展示到页面上,减少开发中的摸索成本。
鸿蒙仓颉语言开发教程:网络请求和数据解析
|
5月前
|
安全 Java Android开发
为什么大厂要求安卓开发者掌握Kotlin和Jetpack?深度解析现代Android开发生态优雅草卓伊凡
为什么大厂要求安卓开发者掌握Kotlin和Jetpack?深度解析现代Android开发生态优雅草卓伊凡
247 0
为什么大厂要求安卓开发者掌握Kotlin和Jetpack?深度解析现代Android开发生态优雅草卓伊凡
|
6月前
|
存储 XML Java
Android 文件数据储存之内部储存 + 外部储存
简介:本文详细介绍了Android内部存储与外部存储的使用方法及核心原理。内部存储位于手机内存中,默认私有,适合存储SharedPreferences、SQLite数据库等重要数据,应用卸载后数据会被清除。外部存储包括公共文件和私有文件,支持SD卡或内部不可移除存储,需申请权限访问。文章通过代码示例展示了如何保存、读取、追加、删除文件以及将图片保存到系统相册的操作,帮助开发者理解存储机制并实现相关功能。
1603 2

热门文章

最新文章

推荐镜像

更多