Android手机应用开发(十) | HttpURLConnection的使用以及解析JSON数据

本文详细介绍了如何在Android应用中使用HttpURLConnection请求Web服务并解析JSON数据。内容涵盖添加依赖、权限设置、网络数据获取、JSON解析、CardView布局技术,以及在RecyclerView中展示数据的完整流程。此外,还讲解了处理网络访问主线程限制、错误响应的策略,以及图片加载和裁剪的相关技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实验目的

  1. 学会使用HttpURLConnection请求访问Web服务
  2. 学习Android线程机制,学会线程更新UI
  3. 学会解析JSON数据
  4. 学习CardView布局技术

效果

效果图

添加依赖

//json解析类
implementation 'com.squareup.retrofit2:converter-gson:2.1.0'
//rxjava类
implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
implementation 'io.reactivex.rxjava2:rxjava:2.2.4'
//recyclerview ui
implementation 'com.android.support:recyclerview-v7:28.0.0'
//cardview ui
implementation'com.android.support:cardview-v7:28.+'

本例使用的RxJava是2.2.4版本,与1.X版本有较大区别!!!

添加权限

app/src/main/AndroidManifest.xml中添加

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

这次的网络访问权限不用动态申请啦!!!

但是

高版本(Android 8以上)的SDK可能会报这样的错误

Cleartext HTTP traffic to xxx not permitted

Google表示,为保证用户数据和设备的安全,针对下一代 Android 系统(Android P) 的应用程序,将要求默认使用加密连接,这意味着 Android P 将禁止 App 使用所有未加密的连接,因此运行 Android P 系统的安卓设备无论是接收或者发送流量,未来都不能明码传输

这里采用最简单的办法

app/src/main/AndroidManifest.xml中的application中添加

android:usesCleartextTraffic="true"

强行使用明文传输

更多办法:https://stackoverflow.com/questions/45940861/android-8-cleartext-http-traffic-not-permitted

使用HttpURLConnection获取网络数据

示例API网址: https://space.bilibili.com/ajax/top/showTop?mid=2

URL url = new URL(baseURL + "showTop?mid=" + editText.getText().toString());
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setConnectTimeout(5000);
conn.setRequestMethod("GET");
if(conn.getResponseCode() == 200){
   
   
    //InputStream转String
    BufferedInputStream bis = new BufferedInputStream((InputStream)conn.getContent());
    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
    int result = bis.read();
    while(result != -1) {
   
   
        byteArrayOutputStream.write((byte) result);
        result = bis.read();
    }
    //结果是byteArrayOutputStream.toString()
}

这样子就可以通过byteArrayOutputStream.toString()得到字符串

不过字符串是JSON类型数据,需要解析才能方便使用

JSON解析类

观察网页返回的json结果

{
   
   "status":true,"data":{
   
   "aid":349,"state":0,"cover":"http:\/\/i2.hdslb.com\/bfs\/archive\/8d15f47650e6e95e11ad7a3d6ae06ea52231169a.jpg","title":"[\u4eba\u751f\u7684\u5bfc\u5e08\u677e\u5188\u4fee\u9020]\u6771\u65b9\u4fee\u5922\u9020","content":"sm5159640","play":186049,"duration":"01:23","video_review":936,"create":"2009-09-08 17:00:16","rec":"e'm'm'm'm'm","count":1}}

根据json中的属性新建实体类RecyclerObj.java

实体类中不要求实现所有的属性

import android.graphics.Bitmap;
import com.google.gson.annotations.SerializedName;
import java.util.ArrayList;
import java.util.List;
public class RecyclerObj {
   
   
    @SerializedName("status")
    private Boolean status;
    @SerializedName("data")
    private data idata;
    public static class data {
   
   
        @SerializedName("aid")
        private String aid;
        @SerializedName("title")
        private String title;
        @SerializedName("cover")
        private String cover;
        @SerializedName("play")
        private String play;
        @SerializedName("duration")
        private String duration;
        //评论
        @SerializedName("video_review")
        private String video_review;
        @SerializedName("create")
        private String create;
        @SerializedName("content")
        private String content;
        public String getAid() {
   
   
            return aid;
        }
        public String getTitle() {
   
   
            return title;
        }
        public String getPlay() {
   
   
            return play;
        }
        public String getVideo_review() {
   
   
            return video_review;
        }
        public String getContent() {
   
   
            return content;
        }
        public String getCover() {
   
   
            return cover;
        }
        public String getCreate() {
   
   
            return create;
        }
        public String getDuration() {
   
   
            return duration;
        }
    }
    public Boolean getStatus() {
   
   
        return status;
    }
    public data getIdata() {
   
   
        return idata;
    }
}    

后来就可以使用new Gson().fromJson(byteArrayOutputStream.toString(), RecyclerObj.class)

String转换为RecyclerObj对象了

还有个实体类PreviewObj.java用来获取预览图的链接返回的JSON数据

package com.sysu.janking.httpapi;

import com.google.gson.annotations.SerializedName;

import java.util.ArrayList;

public class PreviewObj {
   
   
    @SerializedName("code")
    private int code;
    @SerializedName("data")
    private data idata;
    public static class data {
   
   
        @SerializedName("img_x_len")
        private int img_x_len;
        @SerializedName("img_y_len")
        private int img_y_len;
        @SerializedName("img_x_size")
        private int img_x_size;
        @SerializedName("img_y_size")
        private int img_y_size;
        @SerializedName("image")
        private ArrayList<String> image;
        @SerializedName("index")
        private ArrayList<Integer> index;

        public ArrayList<String> getImage() {
   
   
            return image;
        }

        public int getImg_x_len() {
   
   
            return img_x_len;
        }

        public int getImg_x_size() {
   
   
            return img_x_size;
        }

        public int getImg_y_len() {
   
   
            return img_y_len;
        }

        public int getImg_y_size() {
   
   
            return img_y_size;
        }

        public ArrayList<Integer> getIndex() {
   
   
            return index;
        }
    }

    public data getIdata() {
   
   
        return idata;
    }

    public int getCode() {
   
   
        return code;
    }
}

结合RxJava

但是像上面一样直接运行的话会报NetworkOnMainThreadException的异常,因为网络访问不能在主线程中进行,容易造成阻塞或者UI瘫痪

MainActivity.java中添加被观察者

private CompositeDisposable mCompositeDisposable = new CompositeDisposable();
private Observable<RecyclerObj> observable = Observable.create(new ObservableOnSubscribe<RecyclerObj>() {
   
   
    @Override
    public void subscribe(ObservableEmitter<RecyclerObj> observableEmitter) throws Exception {
   
   
        URL url = new URL(baseURL + "showTop?mid=" + editText.getText().toString());
        HttpURLConnection conn = (HttpURLConnection)url.
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值