【Android】OKHTTP使用

如果饿了就吃,困了就睡,渴了就喝,人生就太无趣了
参考博客:https://blog.csdn.net/wsq_tomato/article/details/80301851
Android源码地址:https://github.com/keer123456789/OkHttpExample.git
Springboot后台地址:https://github.com/keer123456789/OkHttpServer.git


1.安装依赖

本次使用的是OKHTTP的3.4.1版本

// https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp
implementation group: 'com.squareup.okhttp3', name: 'okhttp', version: '3.4.1'

2.更改配置

2.1 增加权限

AndroidManifest.xml中增加下面两行权限

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

2.2 添加配置文件

2.2.1 增加xml文件

在资源文件夹res中添加network_security_config.xml(名字随意),内容如下

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

如图1,创建注意选择xml

在这里插入图片描述

目录结构如图2

在这里插入图片描述

2.2.2 更改AndroidManifest.xml文件

AndroidManifest.xml文件中引用刚刚增加的xml文件

android:networkSecurityConfig="@xml/network_security_config"

3.后台接口

后台接口使用SpringBoot开启了一个web服务,有两个接口,分别测试GETPOST方法。

3.1 GET 接口

GET /android/getTest/{info}

返回:Get success

3.2 POST接口

POST /android/postTest/
Data example:
{	
	"name":"keer",
	"pass":"123456"
}

返回:POST success

3.3 后台代码

/**
 * @BelongsProject: okhttpserver
 * @BelongsPackage: com.keer.okhttpserver.Controller
 * @Author: keer
 * @CreateTime: 2020-02-29 22:13
 * @Description: android使用OkHttp后台接口
 */
@RestController()
@RequestMapping("/android")
public class Controller {
    private Logger logger = LoggerFactory.getLogger(Controller.class);

    @RequestMapping(value = "/getTest/{info}", method = RequestMethod.GET)
    public String getMethod(@PathVariable String info) {
        logger.info("接收到Get请求,传来的信息:" + info);
        return "Get success";
    }

    @RequestMapping(value = "/postTest", method = RequestMethod.POST)
    public String postMethod(@RequestBody Map map) {
        logger.info("接收到POST请求,传来的信息:" + map.toString());
        return "Post success!!!";
    }
}

4.Android 中的Activity的XML文件

4.1 代码

<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:stretchColumns="1"
    tools:context=".MainActivity">
    
    <TableRow>
        <TextView
            android:layout_height="wrap_content"
            android:text="Account:" />
        <EditText
            android:id="@+id/account"
            android:layout_height="wrap_content"
            android:hint="Input your account" />
    </TableRow>

    <TableRow>
        <TextView
            android:layout_height="wrap_content"
            android:text="PassWord:" />
        <EditText
            android:id="@+id/password"
            android:layout_height="wrap_content"
            android:inputType="textPassword" />
    </TableRow>

    <Button
        android:id="@+id/get"
        style="@style/Widget.AppCompat.Button"
        android:layout_width="125dp"
        android:layout_height="wrap_content"
        android:text="GET" />

    <Button
        android:id="@+id/post"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:minWidth="32dp"
        android:text="POST" />
</TableLayout>

4.2 图片展示

如图3,模拟登陆界面。

  • 点击GET按钮,会获取Account的输入框的值,作为/android/getTest/{info}接口的info参数;
  • 点击POST按钮,会获取AccountPassWord输入框的值,作为/android/postTest/接口的传送数据。

在这里插入图片描述

5.OKHTTP使用方法

5.1 GET方法使用

	/**
     * @param info 接口中info值
     * @return
     */
    public String myGet(String info) {
        OkHttpClient client = new OkHttpClient();
        //构建请求,request中默认是get方法,所以将.get()删去也不要紧
        Request request = new Request.Builder()
                .url("http://192.168.0.101:8080/android/getTest/" + info)
                //.get() //加上和删去都不要紧
                .build();
        Response response = null;
        String responseData = null;
        try {
            response = client.newCall(request).execute();
            responseData = response.body().string();
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("成功接收到返回值" + responseData);
        return responseData;
    }

5.2 POST方法使用

    public String myPost() throws Exception {
        OkHttpClient client = new OkHttpClient();

		//构建请求头
        final MediaType JSON = MediaType.parse("application/json; charset=utf-8");

		//构建JSON数据,作为传送的数据
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("name", "keer");
        jsonObject.put("pass", "123456");

		//构建RequestBody
        RequestBody body = RequestBody.create(JSON, jsonObject.toString());//这里是需要是json字符串
		
		//构建请求request
        Request request = new Request.Builder()
                .url("http://192.168.0.101:8080/android/postTest")
                .post(body) //将RequestBody作为post方法的参数。
                .build();
        Response response = client.newCall(request).execute();
        String res = response.body().string();
        System.out.println(res);
        return res;
    }

6.主线程和子线程

本人Android小小白,也是看别人的讲解,加上自己的理解,这一部分如有说错,谅解,欢迎指正!!!

6.1 android网络请求

自从android4.0之后,网络请求需要开启线程,原因:

  • 为了避免导致UI卡顿的情况:比如在OnCreate 里面先进行网络请求然后还要加载布局 。
  • 一般大型软件开发时,负责网络通信的,和对数据做处理的,往往是两个不同的模块
    这样通过回调的方式,使代码的耦合性降低,更易于分块。

Android提供了一个消息传递的机制——Handler,来帮助线程之间的通信。

6.2 Handler使用介绍

6.2.1 主线程中创建Handler

在主线程中创建一个Handler实例,,并重写handleMessage()方法,该方法就是子线程动作完成后,需要主线程做的动作。可以看到线程中的通信是通过Message对象实现的。该方法中使用了switch,说明会有两个子线程会发来消息,就是后面调用的postget方法的子线程。switch中的两个动作分别使用Toast对象显示子线程发来的信息。Message对象会在后面介绍。

Handler handler = new Handler() {
	@Override
	public void handleMessage(Message msg) {
		switch (msg.what){
			case 1:{
				Toast.makeText(MainActivity.this, "Get方法成功接收到返回值" + msg.obj.toString(), Toast.LENGTH_SHORT).show();
			}break;
			case 2:{
				Toast.makeText(MainActivity.this, "Post方法成功接收到返回值" + msg.obj.toString(), Toast.LENGTH_SHORT).show();
	 		}break;
		}
	}
};
6.2.2 子线程中发送消息

① GET方法的子线程

	private void getTest(final String name) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                OkHttpClient client = new OkHttpClient();
                Request request = new Request.Builder()
                        .url("http://192.168.0.101:8080/android/getTest/" + name)
                        .build();
                Response response = null;
                String responseData = null;
                try {
                    response = client.newCall(request).execute();
                    responseData = response.body().string();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                System.out.println("成功接收到返回值" + responseData);
                Message message = handler.obtainMessage(1);
                message.obj = responseData;
                handler.sendMessage(message);

            }
        }).start();
    }

② POST方法子线程

	private void postTest(final JSONObject map) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                OkHttpClient client = new OkHttpClient();
                final MediaType JSON = MediaType.parse("application/json; charset=utf-8");//发送json数据的固定写法
                JSONObject jsonObject = new JSONObject();

                RequestBody body = RequestBody.create(JSON, map.toString());//这里是需要是json字符串
                Request request = new Request.Builder()
                        .url("http://192.168.0.101:8080/android/postTest")//用安卓虚拟器跑也不要用127.0.0.1
                        .post(body)
                        .build();
                String res = null;
                try {
                    Response response = client.newCall(request).execute();
                    res = response.body().string();
                    System.out.println(res);
                    Message message = handler.obtainMessage(2);
                    message.obj = res;
                    handler.sendMessage(message);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

可以看出发送消息的主要代码就是下面这三行:

  • 通过已经实例化的handlerobtainMessage()方法实例化Message对象。参数是Message.what的值。
  • 将传送的数据赋值给Messageobj变量。
  • 最后调用sendMessage()方法发送消息
	Message message = handler.obtainMessage(2);
	message.obj = data;
	handler.sendMessage(message);

6.3 Message介绍

通过上面的说明,已经了解Message对象就是线程之间通信的对象,贴出部分声明变量的源码:

  • what就是标记作用,用来区分不同的Message
  • arg1arg2是用来存放需要传递的整数值
  • org传送子线程中的实例化的对象。
    /**
     * User-defined message code so that the recipient can identify
     * what this message is about. Each {@link Handler} has its own name-space
     * for message codes, so you do not need to worry about yours conflicting
     * with other handlers.
     */
    public int what;

    /**
     * arg1 and arg2 are lower-cost alternatives to using
     * {@link #setData(Bundle) setData()} if you only need to store a
     * few integer values.
     */
    public int arg1;

    /**
     * arg1 and arg2 are lower-cost alternatives to using
     * {@link #setData(Bundle) setData()} if you only need to store a
     * few integer values.
     */
    public int arg2;

    /**
     * An arbitrary object to send to the recipient.  When using
     * {@link Messenger} to send the message across processes this can only
     * be non-null if it contains a Parcelable of a framework class (not one
     * implemented by the application).   For other data transfer use
     * {@link #setData}.
     *
     * <p>Note that Parcelable objects here are not supported prior to
     * the {@link android.os.Build.VERSION_CODES#FROYO} release.
     */
    public Object obj;
6.4 全部代码

MainActivity.java中的全部代码如下

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    public static final int SHOW_RESPONSE = 0;
    private Button getbt;
    private Button postbt;
    private EditText accountEdit;
    private EditText passwordEdit;
    private Handler handler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_main);

        getbt = (Button) findViewById(R.id.get);
        postbt = (Button) findViewById(R.id.post);
        accountEdit = (EditText) findViewById(R.id.account);
        passwordEdit = (EditText) findViewById(R.id.password);
        getbt.setOnClickListener(this);
        postbt.setOnClickListener(this);


        handler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                switch (msg.what){
                    case 1:{
                        Toast.makeText(MainActivity.this, "Get方法成功接收到返回值" + msg.obj.toString(), Toast.LENGTH_SHORT).show();
                    }break;
                    case 2:{
                        Toast.makeText(MainActivity.this, "Post方法成功接收到返回值" + msg.obj.toString(), Toast.LENGTH_SHORT).show();
                    }break;
                }

            }
        };
    }

    @Override
    public void onClick(View v) {
        String name = accountEdit.getText().toString();
        String pass = passwordEdit.getText().toString();
        if (v.getId() == R.id.post) {
            JSONObject j = new JSONObject();
            try {
                j.put("name", name);
                j.put("pass", pass);
            } catch (JSONException e) {
                e.printStackTrace();
            }
            postTest(j);
        } else if (v.getId() == R.id.get) {
            getTest(name);
        }
    }

    @Override
    public void onPointerCaptureChanged(boolean hasCapture) {

    }

    /**
     * 发送get请求
     *
     * @param name
     */
    private void getTest(final String name) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                OkHttpClient client = new OkHttpClient();
                Request request = new Request.Builder()
                        .url("http://192.168.0.101:8080/android/getTest/" + name)
                        .build();
                Response response = null;
                String responseData = null;
                try {
                    response = client.newCall(request).execute();
                    responseData = response.body().string();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                System.out.println("成功接收到返回值" + responseData);
                Message message = handler.obtainMessage(1);
                message.obj = responseData;
                handler.sendMessage(message);

            }
        }).start();
    }

    /**
     * 发送POST请求
     *
     * @param map
     */
    private void postTest(final JSONObject map) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                OkHttpClient client = new OkHttpClient();
                final MediaType JSON = MediaType.parse("application/json; charset=utf-8");//发送json数据的固定写法
                JSONObject jsonObject = new JSONObject();

                RequestBody body = RequestBody.create(JSON, map.toString());//这里是需要是json字符串
                Request request = new Request.Builder()
                        .url("http://192.168.0.101:8080/android/postTest")//用安卓虚拟器跑也不要用127.0.0.1
                        .post(body)
                        .build();
                String res = null;
                try {
                    Response response = client.newCall(request).execute();
                    res = response.body().string();
                    System.out.println(res);
                    Message message = handler.obtainMessage(2);
                    message.obj = res;
                    handler.sendMessage(message);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
}

OkHttp是一个处理网络请求的开源项目,是Android使用最广泛的网络框架。它适用于Android 5.0(API级别21)和Java 8。使用OkHttp发送HTTP请求的过程如下: 1. 域名解析(DNS):将域名解析为IP地址。 2. 建立TCP连接:通过三次握手建立TCP连接。 3. 发起HTTP请求:建立TCP连接后,使用Socket输出流将HTTP报文写出。 4. 等待响应:等待服务器响应。 5. 解析响应:解析服务器返回的HTTP响应。 6. 处理响应数据:根据需要处理响应数据,比如解析JSON或下载文件。 在使用OkHttp时,首先需要创建一个Request对象,可以使用Request.Builder()来构建。然后通过Request对象获得一个Call对象,可以使用client.newCall(request)来创建。接下来,可以使用call.execute()进行同步调用或者call.enqueue()进行异步调用。最后,可以通过Response对象获取响应数据。 总之,使用OkHttp很简单,它的请求/响应API使用了流畅的构建器设计和不可变性设计,支持同步阻塞调用和带有回调的异步调用。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [androidOkHttp使用](https://blog.csdn.net/hanjiexuan/article/details/115894233)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [android okhttp的基础使用【入门推荐】](https://download.csdn.net/download/weixin_38516386/12788438)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值