Android学习笔记之使用HTTP协议访问网络

一、使用HttpURLConnection

1.通过URL的openConnection()方法获取一个HttpURLConnection对象

URL url = new URL(mURL);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();

2.设置请求网络的方式

//设置请求类型为GET请求
connection.setRequestMethod("GET");
//设置请求类型为POST请求
connection.setRequestMethod("POST");
DataOutputStream out = new DataOutputStream(connection.getOutputStream());
out.writeBytes("username=admin&password=123123");

PS:POST请求的时候,每一条数据都要以键值对的形式存在,数据与数据之间用“&”符号隔开。

3.请求的自由定制(比如设置连接超时、读取超时的毫秒数)

//设置连接超时的毫秒数
connection.setConnectTimeout(8000);
//设置读取超时的毫秒数
connection.setReadTimeout(8000);

4.获取输入流,拿到请求的结果

//获取字节输入流
InputStream in = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(in));
StringBuilder response = new StringBuilder();
String line = null;
while((line = reader.readLine())!=null){
    response.append(line);
}

5.关闭流

if(reader!=null){
    try {
        reader.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

6.关闭HTTP连接

connection.disconnect();

二、使用OKHttp

1.在app/build.gradle中添加OKHttp库的依赖

implementation 'com.squareup.okhttp3:okhttp:3.11.0'

2.创建一个OkHttpClient实例

OkHttpClient client = new OkHttpClient();

3.创建一个Request对象

GET方式请求:

Request request = new Request.Builder().url(mURL).build();

POST方式请求:

需要先创建一个RequestBody对象来存放待提交的参数,然后在Request.Builder中调用post()方法将其传入:

RequestBody requestBody = new FormBody.Builder()
        .add("username","admin")
        .add("password","123123")
        .build();
Request request = new Request.Builder().url(mURL).post(requestBody).build();

4.再调用OkHttpClient的newCall()方法创建一个Call对象,然后调用其execute()方法来发送请求并获取服务器返回的数据

Response response = client.newCall(request).execute();

5.得到返回的具体内容

String responseData = response.body().string();

三、对请求网络的代码进行封装

因为一个应用程序通常会有很多地方需要请求网络,我们总不能每次请求网络时就再编写一遍上面的代码,因此我们应该将请求网络的代码放到一个公共的类里面,通过调用其静态方法请求网络。除此之外,请求网络属于耗时操作,我们应该开启子线程去请求网络,但是如果我们只是简单的将上述代码放入一个子线程中去执行,那么服务器响应的数据是无法返回的,因为所有的耗时操作都是在子线程中进行的,请求网络的静态方法会在服务器还没来得及响应的时候就已经执行结束了(然后执行静态方法之后的代码,此时还没拿到服务器返回的数据),因此我们封装时还应该利用Java的回调机制来处理返回的数据。

PS:上述的回调接口还是在子线程中运行的,如果我们要更新UI,需要借助runOnUiThread()方法进行线程转换。

1.编写请求网络的回调接口

public interface HttpCallBackListener {
    void onFinish(String response);
    void onError(Exception e);
}

2.对HttpURLConnection请求网络进行封装

public static void sendHttpRequestByPost(final String address, final HttpCallBackListener listener){
    new Thread(new Runnable() {
        HttpURLConnection connection = null;
        BufferedReader reader = null;
        @Override
        public void run() {
            try {
                URL url = new URL(address);
                connection = (HttpURLConnection) url.openConnection();
                connection.setDoInput(true);
                connection.setDoOutput(true);
                //设置请求类型为POST请求
                connection.setRequestMethod("POST");
                DataOutputStream out = new DataOutputStream(connection.getOutputStream());
                out.writeBytes("key="+MainActivity.APP_KEY+"&com="+MainActivity.mCOM+"&no="+MainActivity.mNO+"&dtype=json");
                //设置连接超时的毫秒数
                connection.setConnectTimeout(8000);
                //设置读取超时的毫秒数
                connection.setReadTimeout(8000);
                //获取字节输入流
                InputStream in = connection.getInputStream();
                reader = new BufferedReader(new InputStreamReader(in));
                StringBuilder response = new StringBuilder();
                String line = null;
                while((line = reader.readLine())!=null){
                    response.append(line);
                }
                if(listener!=null){
                    listener.onFinish(response.toString());
                }
            } catch (Exception e) {
                if(listener!=null){
                    listener.onError(e);
                }
            } finally {
                if(reader!=null){
                    try {
                        reader.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if(connection!=null){
                    connection.disconnect();
                }
            }
        }
    }).start();
}

3.对OKHttp请求网络进行封装

public static void sendOkHttpRequestByPost(String address,okhttp3.Callback callback){
    OkHttpClient client = new OkHttpClient();
    //设置返回数据类型为xml/json
    String mDtype = "json";
    //POST方式请求
    RequestBody requestBody = new FormBody.Builder()
            .add("key",MainActivity.APP_KEY)
            .add("com",MainActivity.mCOM)
            .add("no",MainActivity.mNO)
            .add("dtype",mDtype)
            .build();
    Request request = new Request.Builder().url(address).post(requestBody).build();
    client.newCall(request).enqueue(callback);
}

注意:这里没有开启子线程是因为OkHttp在enqueue()方法内部已经帮我们开好子线程了,然后会在子线程中执行HTTP请求,并将最终的结果回调到okhttp3.Callback当中。

okhttp3.Callback的回调方法如下:

HttpUtil.sendOkHttpRequestByPost(mURLpath, new okhttp3.Callback() {
    @Override
    public void onFailure(Call call, IOException e) {
        e.printStackTrace();
    }
    @Override
    public void onResponse(Call call, Response response) throws IOException {
        showResponse(parseJSONWithGSON(response.body().string()));
    }
});

猜你喜欢

转载自blog.csdn.net/Ein3614/article/details/81709498
今日推荐