Okhttp重拾1

package com.example.zhangbiao.okhttpdemo;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

import java.io.IOException;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public class MainActivity extends AppCompatActivity {
  private static final String TAG = "1234";


  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      getDataSync();
      getDataAsync();
      getDataAsyncPOST();

  }


  /*  同步的获得数据
      依赖添加 implementation 'com.squareup.okhttp3:okhttp:3.4.1'
      1 首先获得请求客户端 new OkHttpclient()
      2 获得请求对象  使用 new 静态内部类的形式(Builder是Request的静态内部类 )在调用其build() 方法获得
        其方法链式调用返回的好对象为Request对象

         request的newCall(resopnse对象).execute() 返回response对象

      3 默认情况下使用的get请求  如果的使用post 请求加上post()即可

      4 同步请求的话需要自己开启线程的 更新UI的逻辑要自己切换到主线程

      5 同步使用 用execute 执行

      注意:
      1, Response.code是http响应行中的code,如果访问成功则返回200.这个不是服务器设置的,
         而是http协议中自带的。res中的code才是服务器设置的。注意二者的区别。
      2,response.body().string()本质是输入流的读操作,所以它还是网络请求的一部分,
         所以这行代码必须放在子线程。
      3,response.body().string()只能调用一次,在第一次时有返回值,第二次再调用时将会返回null。
          原因是:response.body().string()的本质是输入流的读操作,必须有服务器的输出流的写操作
          时客户端的读操作才能得到数据。而服务器的写操作只执行一次,所以客户端的读操作也只能执行一次,
          第二次将返回null。

  */
  private void getDataSync() {
      new Thread(new Runnable() {
          @Override
          public void run() {

              OkHttpClient client = new OkHttpClient();
              Request request = new Request.Builder()
                      .url("https://www.baidu.com")
                      .get()//默认的方法 不添加也可以的
                      .build();
              try {
                  Response response = client.newCall(request).execute();
                  if (response.isSuccessful()) {
                      // Log.i(TAG, "返回码 " + response.code());
                      //Log.i(TAG, "message " + response.message());
                      Log.i(TAG, "同步请求数据: " + response.body().string());
                  }
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
      }).start();

  }

  /* 异步的请求数据
   方法与同步的类似 不同点:
   请求不需要开线程 在请求时使用enqueue(callback)方法  参数callback对象

   特别点:  1 enqueue方法会吧请求的网络的代码放入子线程
           2 回调接口 也执行在子线程(onFailure  onResponse)
           3 response.body().string() 必须在子线程中执行 此句代码执行完 代表网络的数据接受完,
             这时才可以 处理数据


*/
  private void getDataAsync() {
      OkHttpClient client = new OkHttpClient();
      final Request request = new Request.Builder()
              .url("https://www.baidu.com")
              .build();
      client.newCall(request).enqueue(new Callback() {
          @Override
          public void onFailure(Call call, IOException e) {

          }

          @Override
          public void onResponse(Call call, Response response) throws IOException {
              if (response.isSuccessful()) {
                  Log.i(TAG, "异步请求数据 :" + response.body().string());
              }
          }
      });
  }

  /*  okhttp post请求
   *   很简单吧 方法改为post就行了只是post需要一个参数 RequestBody对象
   *
   *   故只要是RequestBody对象或者requestbody的子对象都可以
   *   1 FormBody:表单请求体  最简单的字符串提交可以使用 以key value 形式提交
   *
   *
   * */
  private void getDataAsyncPOST() {


      OkHttpClient client = new OkHttpClient();
      final Request request = new Request.Builder()
              .url("https://www.baidu.com")
              .post(null)// 传请求体对象
              .build();
      client.newCall(request).enqueue(new Callback() {
          @Override
          public void onFailure(Call call, IOException e) {

          }

          @Override
          public void onResponse(Call call, Response response) throws IOException {
              if (response.isSuccessful()) {
                  Log.i(TAG, "异步post请求: " + response.body().string());
              }
          }
      });
  }



  // FormBody 类型时 : 只能上传字符串(add源码)
  
  public RequestBody requestBodys() {
       /*


         1 Builder 为FormBody的内部类
         2 内部提供add  addEncoded build 三个方法
           其中add  addEncoded 方法都返回自身对象可以提供链式调用
         3  build 方法返回对象为FormBody类型

         Builder 全部 代码很少 如下:

  public static final class Builder {
  private final List names = new ArrayList<>();
  private final List values = new ArrayList<>();

  public Builder add(String name, String value) {
    names.add(HttpUrl.canonicalize(name, FORM_ENCODE_SET, false, false, true, true));
    values.add(HttpUrl.canonicalize(value, FORM_ENCODE_SET, false, false, true, true));
    return this;
  }

  public Builder addEncoded(String name, String value) {
    names.add(HttpUrl.canonicalize(name, FORM_ENCODE_SET, true, false, true, true));
    values.add(HttpUrl.canonicalize(value, FORM_ENCODE_SET, true, false, true, true));
    return this;
  }

  public FormBody build() {
    return new FormBody(names, values);
  }
}
*/

          FormBody.Builder body = new FormBody.Builder();
          body.add("name", "kevin");
          body.add("age", "22");
          return body.build();
//            TODO 其他类型参见下一篇
  }

}


Okhttp重拾2

你可能感兴趣的:(Okhttp重拾1)