• Android:OkHttp同步请求和异步请求


    一、前言

    网络请求之前工作中用到的是post请求,然后了解之后发现请求的种类还有很多种。下面着重讲到是get和post的同步请求和异步请求。

    二、具体内容

    1.Okhttp的特点:

    • 支持Http/2并允许对同一主机的所有请求共享一套接字;
    • 如果非HTTP/2,则通过连接池,减少了请求延迟;
    • 默认请求GZip压缩数据;
    • 响应缓存,避免了重复请求网络;

    2.get的同步请求

    需要用到的测试网址:

    https://httpbin.org

    测试代码如下:

    1. public class OkhttpTestActivity extends AppCompatActivity {
    2. private OkHttpClient okHttpClient;//新建okHttp请求器
    3. @Override
    4. protected void onCreate(Bundle savedInstanceState) {
    5. super.onCreate(savedInstanceState);
    6. setContentView(R.layout.activity_okhttp_test);
    7. okHttpClient = new OkHttpClient();
    8. }
    9. public void getSync(View view){//get同步请求
    10. /**
    11. * 括号里是请求的域名以及需要上传的参数
    12. * 如果需要上传参数只需要在请求域名后面加一个?a=1&b=2
    13. */
    14. new Thread(){
    15. @Override
    16. public void run() {
    17. Request request = new Request.Builder().url("https://httpbin.org/get?a=1&b=2").build();
    18. //一个准备好请求的call对象
    19. Call call = okHttpClient.newCall(request);
    20. try {
    21. Response response = call.execute();
    22. System.out.println(response.body().string());
    23. } catch (IOException e) {
    24. throw new RuntimeException(e);
    25. }
    26. super.run();
    27. }
    28. }.start();
    29. }
    30. }

    运行结果截图

    使用get同步请求时遇到的问题如下

    之前写代码是这样的

    1. public void getSync(View view){//get同步请求
    2. /**
    3. * 括号里是请求的域名以及需要上传的参数
    4. * 如果需要上传参数只需要在请求域名后面加一个?a=1&b=2
    5. */
    6. new Thread(){
    7. @Override
    8. public void run() {
    9. Request request = new Request.Builder().url("https://httpbin.org/get?a=1&b=2").build();
    10. //一个准备好请求的call对象
    11. Call call = okHttpClient.newCall(request);
    12. try {
    13. Response response = call.execute();
    14. System.out.println(response.body().toString());
    15. } catch (IOException e) {
    16. throw new RuntimeException(e);
    17. }
    18. super.run();
    19. }
    20. }.start();

    在获取请求体的时候用response.body().toString();报错如下

    修改方案:

    1. public void getSync(View view){//get同步请求
    2. /**
    3. * 括号里是请求的域名以及需要上传的参数
    4. * 如果需要上传参数只需要在请求域名后面加一个?a=1&b=2
    5. */
    6. new Thread(){
    7. @Override
    8. public void run() {
    9. Request request = new Request.Builder().url("https://httpbin.org/get?a=1&b=2").build();
    10. //一个准备好请求的call对象
    11. Call call = okHttpClient.newCall(request);
    12. try {
    13. Response response = call.execute();
    14. System.out.println(response.body().string());
    15. } catch (IOException e) {
    16. throw new RuntimeException(e);
    17. }
    18. super.run();
    19. }
    20. }.start();
    21. }

    把请求体改成response.body().string()就好了

    总结:同步请求要等call.execute执行完成之后再执行接下去的代码

    3.get的异步请求

    知识点补充:

      1.异步请求和同步请求的区别时异步请求调用的是enqueue方法。然后传递一个回调对象给              enqueue方法,需要用到callback方法中的两个接口回调。callback中有两个接口需要实现,一        个是请求失败的回调接口另一个是请求结束的回调接口
      2.需要注意的的是请求码是200成功404失败,无论是200~299还是404都会调用结束的接口所以       当调用onResponse接口时也不意味者接口调用成功了
      3.当调用response只意味着我们跟服务器之间的通信是成功的,处理数据不一定成功。
      4.200~300之间代表成功300~400代表重定向400~~500代表服务器错误

    1. public class OkhttpTestActivity extends AppCompatActivity {
    2. private OkHttpClient okHttpClient;//新建okHttp请求器
    3. @Override
    4. protected void onCreate(Bundle savedInstanceState) {
    5. super.onCreate(savedInstanceState);
    6. setContentView(R.layout.activity_okhttp_test);
    7. okHttpClient = new OkHttpClient();
    8. }
    9. public void getAync(View view) {//get异步请求
    10. Request request = new Request.Builder().url("https://httpbin.org/get?a=1&b=2").build();
    11. //一个准备好请求的call对象
    12. Call call = okHttpClient.newCall(request);
    13. //异步请求和同步请求的区别时异步请求调用的是enqueue方法然后传递一个回调对象给enqueue方法,callback中有两个接口需要实现,一个是请求失败的回调接口另一个是请求结束的回调接口
    14. //需要注意的的是请求码是200成功404失败,无论是200~299还是404都会调用结束的接口所以当调用onResponse接口时也不意味者接口调用成功了
    15. //当response出现200是只意味着我们跟服务器之间的通信是成功的,处理数据不一定成功
    16. //200~300之间代表成功300~400代表重定向400~~500代表服务器错误
    17. call.enqueue(new Callback() {
    18. @Override
    19. public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
    20. if (response.isSuccessful()) {
    21. System.out.println(response.body().string());
    22. }
    23. }
    24. @Override
    25. public void onFailure(@NonNull Call call, @NonNull IOException e) {
    26. }
    27. });
    28. }
    29. }

    运行结果

    总结:异步请求不会等服务器请求完成之后再去执行后面的代码enqueue内部就会帮我们创建子线程我们不需要自己再创建子线程。 

    4.post同步请求

    注意点:OkHttp默认创建出来的request是get请求

    get请求和post请求的区别:get请求需要加在url的后面,然而post请求需要把请求参数放在请求体里面

    测试代码:

    1. public class OkhttpTestActivity extends AppCompatActivity {
    2. private OkHttpClient okHttpClient;//新建okHttp请求器
    3. @Override
    4. protected void onCreate(Bundle savedInstanceState) {
    5. super.onCreate(savedInstanceState);
    6. setContentView(R.layout.activity_okhttp_test);
    7. okHttpClient = new OkHttpClient();
    8. }
    9. public void postSync(View view) {//post同步请求
    10. FormBody formBody = new FormBody.Builder().add("a", "1").add("b", "2").build();
    11. Request request = new Request.Builder().url("https://httpbin.org/post").post(formBody).build();
    12. new Thread(){
    13. @Override
    14. public void run() {
    15. //一个准备好请求的call对象
    16. Call call = okHttpClient.newCall(request);
    17. try {
    18. Response response = call.execute();
    19. System.out.println(response.body().string());
    20. } catch (IOException e) {
    21. throw new RuntimeException(e);
    22. }
    23. super.run();
    24. }
    25. }.start();
    26. }
    27. }

    测试结果:

    5.post异步请求

    测试代码

    1. public class OkhttpTestActivity extends AppCompatActivity {
    2. private OkHttpClient okHttpClient;//新建okHttp请求器
    3. @Override
    4. protected void onCreate(Bundle savedInstanceState) {
    5. super.onCreate(savedInstanceState);
    6. setContentView(R.layout.activity_okhttp_test);
    7. okHttpClient = new OkHttpClient();
    8. }
    9. public void postAync(View view) {//post异步请求
    10. FormBody formBody = new FormBody.Builder().add("a", "1").add("b", "2").build();
    11. Request request = new Request.Builder().url("https://httpbin.org/post").post(formBody).build();
    12. //一个准备好请求的call对象
    13. Call call = okHttpClient.newCall(request);
    14. call.enqueue(new Callback() {
    15. @Override
    16. public void onFailure(@NonNull Call call, @NonNull IOException e) {
    17. }
    18. @Override
    19. public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
    20. System.out.println(response.body().string());
    21. }
    22. });
    23. }
    24. }

    测试结果

    6.测试请求的页面布局

    我在一个页面上放置了四个按钮代码如下:

    1. "1.0" encoding="utf-8"?>
    2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    3. xmlns:app="http://schemas.android.com/apk/res-auto"
    4. xmlns:tools="http://schemas.android.com/tools"
    5. android:layout_width="match_parent"
    6. android:layout_height="match_parent"
    7. android:orientation="vertical"
    8. tools:context=".ui.study.OkhttpTestActivity">
    9. <Button
    10. android:layout_width="match_parent"
    11. android:layout_height="wrap_content"
    12. android:onClick="getSync"
    13. android:text="GET同步请求"/>
    14. <Button
    15. android:layout_width="match_parent"
    16. android:layout_height="wrap_content"
    17. android:onClick="getAync"
    18. android:text="GET异步请求"/>
    19. <Button
    20. android:layout_width="match_parent"
    21. android:layout_height="wrap_content"
    22. android:onClick="postSync"
    23. android:text="POST同步请求"/>
    24. <Button
    25. android:layout_width="match_parent"
    26. android:layout_height="wrap_content"
    27. android:onClick="postAync"
    28. android:text="POST异步请求"/>
    29. LinearLayout>

    总结:post请求和get请求参数位置不同post要放到FormBody里面其他的相差不大,最后希望可以帮到你。

  • 相关阅读:
    ansible批量安装docker
    ubuntu突然进不了图形界面解决方案
    智能家居——libcurl库简介
    策略模式
    AI教程视频 - 零基础玩转illustrator科研绘图-内容介绍-目录
    【消息中心】kafka消费失败重试10次的问题
    [当人工智能遇上安全] 9.基于API序列和深度学习的恶意家族分类实例详解
    es(网站的搜索技术)
    数据结构刷题:第八天
    Java包
  • 原文地址:https://blog.csdn.net/Rssqzqyp/article/details/134262043