Android --- 网络请求

通常在 Android 中进行网络连接一般使用 Scoket 和HTTP,HTTP 请求方式比 Scoket 多。HTTP 请求一般采用原生的 HttpClient 和 HttpUrlConnection 的两种网络访问方式(系统自带的)。但是在 Android 5.0 的时候 Google 就不推荐使用 HttpClient 了,到了 Android 6.0 (api 23) SDK,不再提供 org.apache.http.* (只保留几个类), 因此,设置 android SDK 的编译版本为23时,且使用了 httpClient 相关类的库项目:如 android-async-http 等等,会出现有一些类找不到的错误。

添加权限

开始网络请求之前应该在清单文件中添加网络权限

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

HttpURLConnection

1. 实例化一个 URL 对象

2.获取 HttpURLConnection 实例,使用URL的

3.设置请求相关属性

4. 获取响应码 200 成功 404 未请求到指定资源 500 服务器异常(此时已经发起请求)

5.判断响应码并获取响应数据(响应的正文)

    // get 请求方法
    public void GetHttp(){
        try {
            // 1. 实例化一个 URL 对象
            URL url = new URL("https://reqres.in/api/users");

            // 2. 获取 HttpURLConnection 实例,使用URL的
            HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();

            // 3. 设置请求相关属性
            httpURLConnection.setRequestMethod("GET"); // 请求方法
            httpURLConnection.setConnectTimeout(6000); // 超时时间

            // 4. 获取响应码 200 成功 404 未请求到指定资源 500 服务器异常(此时已经发起请求)
            if( httpURLConnection.getResponseCode() == HttpURLConnection.HTTP_OK){
                // 5.判断响应码并获取响应数据(响应的正文)
                InputStream inputStream = httpURLConnection.getInputStream(); // 获取了服务器返回的输入流
                byte[] bytes = new byte[1024]; // bytes 数组,每次最多可以存放 1024 个字节
                ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); // 存储从输入流中读取的数据
                int len = 0;
                // 输入流中读取数据,然后将数据写入ByteArrayOutputStream中
                /* inputStream.read(bytes) :从输入流中读取数据,并将读取的内容存储到bytes数组中
                 * 这个方法的返回值是读取的字节数,如果已经到达流的末尾,它会返回-1
                 * len = inputStream.read(bytes) 是用来判断是否已经读到了末尾*/
                while((len = inputStream.read(bytes)) >-1){
                    // 将字节数组中的内容写入到缓存流
                    /* 参数1:要存入的字节数组
                     * 参数2:起点
                     * 参数3:要存入的长度*/
                    byteArrayOutputStream.write(bytes,0,len);
                }
                String s = new String(byteArrayOutputStream.toByteArray()) ;
                Log.e("GET_NetWork",s);
            }
        } catch (MalformedURLException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);

post请求

1.更多会做提交数据和存储数据
2.参数会作为单独的一部分传递过去,不像GET一样会追加在URL后面

// POST 请求方法
    private void PostHttp() {
        try {
            // 1. 实例化一个 URL 对象
            URL url = new URL("https://www.wanandroid.com/user/login");

            // 2. 获取 HttpURLConnection 实例,使用URL的
            HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();

            // 3. 设置请求相关属性
            httpURLConnection.setRequestMethod("POST"); // 请求方法
            httpURLConnection.setConnectTimeout(6000); // 超时时间
            httpURLConnection.setDoOutput(true); // 设置允许输出
            httpURLConnection.setRequestProperty("Content-Type","application/json;Charset=UTF-8");// 设置提交数据的类型

            // 4.获取输出流(请求正文)
            OutputStream out = httpURLConnection.getOutputStream();
            // 5.写数据
            out.write(("username="+"akshfalwhfaina"+"&password="+"123456").getBytes());

            if( httpURLConnection.getResponseCode() == HttpURLConnection.HTTP_OK){
                // 6.判断响应码并获取响应数据(响应的正文)
                InputStream inputStream = httpURLConnection.getInputStream(); // 获取了服务器返回的输入流
                byte[] bytes = new byte[1024]; // bytes 数组,每次最多可以存放 1024 个字节
                ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); // 存储从输入流中读取的数据
                int len = 0;
                // 输入流中读取数据,然后将数据写入ByteArrayOutputStream中
                /* inputStream.read(bytes) :从输入流中读取数据,并将读取的内容存储到bytes数组中
                 * 这个方法的返回值是读取的字节数,如果已经到达流的末尾,它会返回-1
                 * len = inputStream.read(bytes) 是用来判断是否已经读到了末尾*/
                while((len = inputStream.read(bytes)) >-1){
                    // 将字节数组中的内容写入到缓存流
                    /* 参数1:要存入的字节数组
                     * 参数2:起点
                     * 参数3:要存入的长度*/
                    byteArrayOutputStream.write(bytes,0,len);
                }
                String s = new String(byteArrayOutputStream.toByteArray()) ;
                Log.e("POST_NetWork",s);
            }

        } catch (MalformedURLException e) {
            throw new RuntimeException(e);
        } catch (ProtocolException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

Volley

GitHub - google/volley

volley适用于数据量不大、通信频繁的场景,如:带图片的列表

添加依赖:

dependencies {
   implementation ("com.android.volley:volley:1.2.1")
}

常用api:

RequestQueue:请求队列,会自动执行队列中的请求

  • Volley.newRequestQueue(context) 创建一个请求队列
 public static RequestQueue newRequestQueue(Context context)
  • RequestQueue.add(Request<T> request) 添加一个请求到请求队列
public <T> Request<T> add(Request<T> request)

 Request<T> :代表请求的接口

  • StringRequest:获取字符串结果的请求

 public StringRequest(int method,String url,Listener<String> listener, @Nullable ErrorListener errorListener) 
  • JsonRequest:获取json数据结果的请求,不过由于JsonRequest是一个抽象类,因此我们无法直接创建它的实例,那么只能从它的子类入手了。JsonRequest有两个直接的子类,JsonObjectRequest和JsonArrayRequest,它返回的对象是JSONObject。

public JsonObjectRequest(String url, Listener<JSONObject> listener, @Nullable ErrorListener errorListener)
 public JsonArrayRequest(String url, Listener<JSONArray> listener, @Nullable ErrorListener errorListener)
  • ImageRequest:获取图片结果的请求

public ImageRequest(
   String url,
   Response.Listener<Bitmap> listener,
   int maxWidth,
   int maxHeight,
   ScaleType scaleType,
   Config decodeConfig,
   @Nullable Response.ErrorListener errorListener);

步骤:

创建请求队列

创建请求对象

添加请求 

Get请求

    public String url = "https://reqres.in/api/users";
    public void toLearnVolley(View view){
        // 1.创建请求队列
        RequestQueue requestQueue = Volley.newRequestQueue(this);
        // 2.创建请求
        StringRequest stringRequest = new StringRequest(com.android.volley.Request.Method.GET, url, new com.android.volley.Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                Log.e("volley---成功",response);
            }
        }, new com.android.volley.Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Log.e("volley---失败",error.toString());
            }
        });
        // 3.将请求加入请求队列
        requestQueue.add(stringRequest);
    }

Post请求

volley中并没有提供设置POST参数的方法,但是当发出POST请求的时候,Volley会尝试调用StringRequest的父类——Request中的getParams()方法来获取POST参数,所以需要在Request的匿名类中重写getParams()方法

 public String postUrl = "https://www.wanandroid.com/user/login";
    public void toLearnVolleyPost(View view){
        // 如何放入请求体?
        StringRequest stringPostRequest = new StringRequest(com.android.volley.Request.Method.POST, postUrl, new com.android.volley.Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                Log.e("volley---Post成功",response);
            }
        }, new com.android.volley.Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Log.e("volley---Post失败",error.toString());
            }
        }){
            @Nullable
            @Override
            // 重写此方法返回参数的map作为请求体
            protected Map<String, String> getParams() throws AuthFailureError {
                Map<String,String> map = new HashMap<String,String>();
                map.put("username","akshfalwhfaina");
                map.put("password","123456");
                return map;
            }
        };
        requestQueue.add(stringPostRequest);
    }

OkHttp

添加依赖

在build.gradle.kts中添加依赖

dependencies {
    // 添加okhttp的依赖
    implementation("com.squareup.okhttp3:okhttp:4.11.0")
}

 get请求

    public void toLearnOKhttp(View view) {
        // 创建一个 OKhttp 客户端
        OkHttpClient okHttpClient = new OkHttpClient();
        // 创建一个 http 请求
        Request request = new Request.Builder().url("https://reqres.in/api/users").get().build();
        // Call 是一个即将准备好被执行的请求
        Call call = okHttpClient.newCall(request);
        // 执行请求,并定义回调函数
        // 请求成功后数据封装在response的body里面
        call.enqueue(new Callback() {
            @Override
            public void onFailure(@NonNull Call call, @NonNull IOException e) {
                Log.e("okhttp-----失败","okhttp失败");
            }

            @Override
            public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
                if(response.isSuccessful()){
                    String data = response.body().string();
                    Log.i("okhttp-----成功",data);
       
                }
            }
        });
    }

post请求

POST请求将参数放在请求的主体中,不会直接显示在URL中。

public void toLearnOKhttpPost(View view){
        // 创建一个 OKhttp 客户端
        OkHttpClient okHttpClient = new OkHttpClient();
        // 创建一个 http 请求
        RequestBody body = new FormBody.Builder().add("username","akshfalwhfaina").add("password","123456").build();
        Request request = new Request.Builder().url("https://www.wanandroid.com/user/login").post(body).build();
        Call call = okHttpClient.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(@NonNull Call call, @NonNull IOException e) {
                Log.e("okhttp-----post失败",e.toString());

            }

            @Override
            public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
                Log.e("okhttp-----post成功",response.toString());
            }
        });
    }

Json数据解析

json对象:花括号开头和结尾,中间是键值对形式————”属性”:属性值””

json数组:中括号里放置 json 数组,里面是多个json对象或者数字等

JSONObject

利用 JSONObject 解析
1.创建 JSONObject 对象,传入满足 json 格式的字符串
2.根据 json数据的key键值 获取其中的数据,是什么类型的数据就写getxx()
3.getJSONObject("xxx") 获取JSONObject对象
4.getJSONArray("xxx") 获取json数组
5.jsonArray.getJSONObject(i) 获取数组中的第 i 个json对象

请求返回的数据如下:

JSONObject jsonObject = new JSONObject(data);
Log.i("okhttp-----成功","总共数量"+jsonObject.getString("total"));
// data 里面是 json 数组,数组里面放的是多个 json 对象
JSONArray jsonArray = jsonObject.getJSONArray("data");
for (int i = 0; i < jsonArray.length(); i++) {
   JSONObject jo = jsonArray.getJSONObject(i); // 获取数组中的第 i 个对象
   String text1 = jo.getString("email");
   Log.i("okhttp-----成功--邮箱","邮箱"+text1);
    }
} catch (JSONException e) {
     throw new RuntimeException(e);
}

Gson解析

用第三方工具来解析json数据

添加依赖

// 1.添加 gson 依赖
implementation("com.google.code.gson:gson:2.8.9")
  • 创建 Bean 对象(数据对象),注意,元素和返回的数据的元素要一一对应。
  • toJson:将 bean 对象转换成 json 字符串
  • fromJson:将 json 字符串转换成 bean 对象
package com.example.androidstudiostudy.data;

import java.util.List;

// 一个json 的数据对象(来自于GET返回的 json 字符串)
public class OneJsonBean {
    private int page;
    private int per_page;
    private int total;
    private int total_pages;
    private List<DataBean> data;

    @Override
    public String toString() {
        return "OneJsonBean对象{" +
                "page=" + page +
                ", per_page=" + per_page +
                ", total=" + total +
                ", total_pages=" + total_pages +
                ", data=" + data +
                '}';
    }
}

package com.example.androidstudiostudy.data;

// 此时的 DataBean 是 GET 返回的json字符串中 data的json对象
public class DataBean {
    private int id;
    private String email;
    private String first_name;
    private String last_name;
    private String avatar;

    public DataBean(int id, String email, String first_name, String last_name, String avatar) {
        this.id = id;
        this.email = email;
        this.first_name = first_name;
        this.last_name = last_name;
        this.avatar = avatar;
    }

    public int getId() {
        return id;
    }

    public String getEmail() {
        return email;
    }

    public String getFirst_name() {
        return first_name;
    }

    public String getLast_name() {
        return last_name;
    }

    public String getAvatar() {
        return avatar;
    }

    @Override
    public String toString() {
        return "DataBean{" +
                "id=" + id +
                ", email='" + email + '\'' +
                ", first_name='" + first_name + '\'' +
                ", last_name='" + last_name + '\'' +
                ", avatar='" + avatar + '\'' +
                '}';
    }
}
// Gson解析json数据
Gson gson = new Gson();
OneJsonBean  oneJsonBean = gson.fromJson(data, OneJsonBean.class);
Log.e("okhttp-----成功--数据转换成对象",oneJsonBean.toString());

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值