Android OkHttp的简单使用和封装详解

Android OkHttp的简单使用和封装详解,第1张

概述AndroidOkHttp的简单使用和封装详解1,昨天把okHttp仔细的看了一下,以前都是调用同事封装好了的网络框架,直接使用很容易,但自己封装却不是那么简单,还好,今天就来自我救赎一把,就和大家写写从最基础的OKHttp的

AndroID Okhttp的简单使用和封装详解

1,昨天把okhttp仔细的看了一下,以前都是调用同事封装好了的网络框架,直接使用很容易,但自己封装却不是那么简单,还好,今天就来自我救赎一把,就和大家写写从最基础的OKhttp的简单get、post的使用,再到它的封装。

2,Okhttp的简单使用

  首先我们创建一个工程,并在布局文件中添加三个控件,TextVIEw(用于展示获取到Json后的信息)、button(点击开始请求网络)、Progressbar(网络加载提示框)

  ①简单的异步Get请求

  第一步,创建OKhttpClIEnt对象

  第二步,创建Request请求

  第三步,创建一个Call对象

  第四步,将请求添加到调度中

  不多说,直接上代码:

//okhttp的基本使用 --- get方法  String url = "https://API.douban.com/v2/movIE/top250?start=0&count=10";  //1,创建OKhttpClIEnt对象  OkhttpClIEnt mOkhttpClIEnt = new OkhttpClIEnt();  //2,创建一个Request  Request request = new Request.Builder().url(url).build();  //3,创建一个call对象  Call call = mOkhttpClIEnt.newCall(request);  //4,将请求添加到调度中  call.enqueue(new Callback() {    @OverrIDe    public voID onFailure(Request request,IOException e) {     }     @OverrIDe    public voID onResponse(Response response) throws IOException {      if (response.isSuccessful()) {        final String message = response.body().string();        handler.post(new Runnable() {          @OverrIDe          public voID run() {            tv_message.setText(message);            progressbar.setVisibility(VIEw.GONE);          }        });       }    }   });

 效果如下: 

  

  注意,由于我们调用的enqueue()方法,是运行在网络线程中的,所以当我们得到Json数据后想要获取更新UI的话,可以开使用handle.post()方法在run方法里面更新UI。

  ② 简单的异步Post请求

  这里的Post请求我们以最常见的注册登录来举例。post请求的步骤和get是相似的只是在创建Request的 时候将服务器需要的参数传递进去.

  代码如下:

String url = "http://192.168.1.123:8081/API/login";    //1,创建OKhttpClIEnt对象    OkhttpClIEnt mOkhttpClIEnt = new OkhttpClIEnt();    //2,创建Request    Requestbody formBody = new FormEnCodingBuilder()        .add("username","superadmin")        .add("pwd","ba3253876aed6bc22d4a6ff53d8406c6ad864195ed144ab5c87621b6c233b548baeae6956df346ec8c17f5ea10f35ee3cbc514797ed7ddd3145464e2a0bab413")        .build();     Request request = new Request.Builder().url(url).post(formBody).build();    //3,创建call对象并将请求对象添加到调度中    mOkhttpClIEnt.newCall(request).enqueue(new Callback() {      @OverrIDe      public voID onFailure(Request request,IOException e) {       }       @OverrIDe      public voID onResponse(Response response) throws IOException {        Log.i("wangjitao",response.body().string());      }    });

  看一下我们服务器的断点

  

  可以看到我们服务器的确拿到了我们传递参数,再看一下我们请求后拿到的数据

  ok,这样的话我们的post方法就没什么问题了

3,Okhttp的封装

由于是封装我们可以吧OKhttp和Gson给结合起来,那么我们在gradle文件添加以下的依赖

compile "com.squareup.okhttp:okhttp:2.4.0"compile 'com.squareup.okio:okio:1.5.0'compile "com.Google.code.gson:gson:2.8.0"

  ①CallBack的创建  

  首选我们知道,当接口请求成功或者失败的时候我们需要将这个信息通知给用户,那么我们就需要创建一个抽象类RequestCallBack,请求前、成功、失败、请求后这几个方法,创建OnBefore()、OnAfter()、OnError()、OnResponse()对应

/** * 在请求之前的方法,一般用于加载框展示 * * @param request */public voID onBefore(Request request) {} /** * 在请求之后的方法,一般用于加载框隐藏 */public voID onAfter() {} /** * 请求失败的时候 * * @param request * @param e */public abstract voID onError(Request request,Exception e); /** * * @param response */public abstract voID onResponse(T response);

 由于我们每次想要的数据不一定,所以这里我们用<T>来接收想要装成的数据格式,并通过反射得到想要的数据类型(一般是Bean、List)之类 ,所以RequestCallBack的整体代码如下:

package com.qianmo.httprequest.http; import com.Google.gson.internal.$Gson$Types;import com.squareup.okhttp.Request; import java.lang.reflect.ParameterizedType;import java.lang.reflect.Type;  /** * Created by wangjitao on 15/10/16. * 抽象类,用于请求成功后的回调 */public abstract class ResultCallback<T> {  //这是请求数据的返回类型,包含常见的(Bean,List等)  Type mType;   public ResultCallback() {    mType = getSuperclasstypeParameter(getClass());  }   /**   * 通过反射想要的返回类型   *   * @param subclass   * @return   */  static Type getSuperclasstypeParameter(Class<?> subclass) {    Type superclass = subclass.getGenericSuperclass();    if (superclass instanceof Class) {      throw new RuntimeException("Missing type parameter.");    }    ParameterizedType parameterized = (ParameterizedType) superclass;    return $Gson$Types.canonicalize(parameterized.getActualTypeArguments()[0]);  }   /**   * 在请求之前的方法,一般用于加载框展示   *   * @param request   */  public voID onBefore(Request request) {  }   /**   * 在请求之后的方法,一般用于加载框隐藏   */  public voID onAfter() {  }   /**   * 请求失败的时候   *   * @param request   * @param e   */  public abstract voID onError(Request request,Exception e);   /**   *   * @param response   */  public abstract voID onResponse(T response);}

  ②对Get、Post方法的简单封装 

  首先我们创建一个OkhttpClIEntManager类,由于是管理类,所以,单例加静态对象搞起

private static OkhttpClIEntManager mInstance;  public static OkhttpClIEntManager getInstance() {    if (mInstance == null){      synchronized (OkhttpClIEntManager.class) {        if (mInstance == null) {          mInstance = new OkhttpClIEntManager();        }      }    }    return mInstance;  }

 在创建Manager对象的时候我们要把Okhttp的一些参数配置一下,顺便一提一下,由于我们我们异步get、post方法是运行在子线程中,所以这里我们添加了分发的 Handler mDelivery;,重写的OkhttpClIEntManager构造方法如下:

private OkhttpClIEntManager() {    mOkhttpClIEnt = new OkhttpClIEnt();    mOkhttpClIEnt.setConnectTimeout(10,TimeUnit.SECONDS);    mOkhttpClIEnt.setWriteTimeout(10,TimeUnit.SECONDS);    mOkhttpClIEnt.setReadTimeout(30,TimeUnit.SECONDS);    //cookie enabled    mOkhttpClIEnt.setcookieHandler(new cookieManager(null,cookiePolicy.ACCEPT_ORIGINAL_SERVER));    mDelivery = new Handler(Looper.getMainLooper());    mGson = new Gson();  }

  前面的外部调用对象封装好了,这里我们开始来封装Get或Post方法,我这里以Post方法为例子,首先分析一下,post方法会有几个参数,参数一url,参数二参数params,参数三Callback(及我们上面的RequestCallBack)参数四flag(用于取消请求 *** 作,可为空),基础代码如下:

/**    * 通用基础的异步的post请求    * @param url    * @param callback    * @param tag    */    public voID postAsyn(String url,Param[] params,final ResultCallback callback,Object tag) {      Request request = buildPostFormRequest(url,params,tag);      deliveryResult(callback,request);    }

  那么我们再看一下deliveryResult方法到底是干什么的

/**  * 请求回调处理方法并传递返回值  * @param callback Map类型请求参数  * @param request Request请求  */  private voID deliveryResult(ResultCallback callback,Request request) {    if (callback == null)      callback = DEFAulT_RESulT_CALLBACK;    final ResultCallback resCallBack = callback;    //UI thread    callback.onBefore(request);    mOkhttpClIEnt.newCall(request).enqueue(new Callback() {      @OverrIDe      public voID onFailure(final Request request,final IOException e) {        sendFailedStringCallback(request,e,resCallBack);      }       @OverrIDe      public voID onResponse(final Response response) {        try {          final String responseMessage=response.message();          final String responseBody = response.body().string();          if(response.code()==200){            if (resCallBack.mType == String.class) {              sendSuccessResultCallback(responseBody,resCallBack);            } else {              Object o = mGson.fromJson(responseBody,resCallBack.mType);              sendSuccessResultCallback(o,resCallBack);            }          }else{            Exception exception=new Exception(response.code()+":"+responseMessage);            sendFailedStringCallback(response.request(),exception,resCallBack);          }        } catch (IOException e) {          sendFailedStringCallback(response.request(),resCallBack);        } catch (com.Google.gson.JsonParseException e) {//Json解析的错误          sendFailedStringCallback(response.request(),resCallBack);        }      }    });  }

  可以看到,这个方法主要是发出请求并对请求后的数据开始回调,这样我们就基本上封装好了一个post方法了  ,把代码这一部分的代码贴出来看看

public class OkhttpClIEntManager {  private static final String TAG = "com.qianmo.httprequest.http.OkhttpClIEntManager";   private static OkhttpClIEntManager mInstance;  //默认的请求回调类  private final ResultCallback<String> DEFAulT_RESulT_CALLBACK = new ResultCallback<String>(){    @OverrIDe    public voID onError(Request request,Exception e) {}     @OverrIDe    public voID onResponse(String response) {}  };  private OkhttpClIEnt mOkhttpClIEnt;  private Handler mDelivery;  private Gson mGson;  private GetDelegate mGetDelegate = new GetDelegate();  private PostDelegate mPostDelegate = new PostDelegate();  private DownloadDelegate mDownloadDelegate = new DownloadDelegate();   private OkhttpClIEntManager() {    mOkhttpClIEnt = new OkhttpClIEnt();    mOkhttpClIEnt.setConnectTimeout(10,cookiePolicy.ACCEPT_ORIGINAL_SERVER));    mDelivery = new Handler(Looper.getMainLooper());    mGson = new Gson();  }   public static OkhttpClIEntManager getInstance() {    if (mInstance == null){      synchronized (OkhttpClIEntManager.class) {        if (mInstance == null) {          mInstance = new OkhttpClIEntManager();        }      }    }    return mInstance;  }   /**   * 外部可调用的Post异步请求方法   * @param url 请求url   * @param params   * @param callback 请求完成后回调类   */  public static voID postAsyn(String url,Map<String,String> params,final ResultCallback callback) {    getInstance().getPostDelegate().postAsyn(url,callback,null);  }   /**     * 异步的post请求     * @param url     * @param params     * @param callback     * @param tag     */    public voID postAsyn(String url,Object tag) {      Param[] paramsArr = map2Params(params);      postAsyn(url,paramsArr,tag);    }  /**     * 通用基础的异步的post请求     * @param url     * @param callback     * @param tag     */    public voID postAsyn(String url,request);    }     /**   * 请求回调处理方法并传递返回值   * @param callback Map类型请求参数   * @param request Request请求   */  private voID deliveryResult(ResultCallback callback,resCallBack);        }      }    });  }   /**   * 处理请求成功的回调信息方法   * @param object 服务器响应信息   * @param callback 回调类   */  private voID sendSuccessResultCallback(final Object object,final   ResultCallback callback) {    mDelivery.post(() -> {      callback.onResponse(object);      callback.onAfter();    });  }}  

  这样我们就把Post方法封装好了,同理Get方法,ok,现在我们可以来调用调用了,在调用之前我们可以对返回数据格式再来封装封装,一般我们后台返回的数据格式是类似如下:

{ "code": 200,"data": {},"message": "登录成功"}

 而data中有可能是对象,也有可能是数组,所以我们用两个类来实现一下

 CommonResultBean

package com.qianmo.httprequest.bean; /** * 服务端返回通用接收实体 * Created by wangjitao on 15/10/30. */public class CommonResultBean<T> {  private String code;  private T data;  private String message;   public String getCode() {    return code;  }   public voID setCode(String code) {    this.code = code;  }   public T getData() {    return data;  }   public voID setData(T data) {    this.data = data;  }   public String getMessage() {    return message;  }   public voID setMessage(String message) {    this.message = message;  }}

 CommonResultListBean

package com.qianmo.httprequest.bean; import java.util.List; /** * 服务端返回带有List数据的通用接收实体 * Created by wangjitao on 15/12/1. */public class CommonResultListBean<T> {  private String code;  private List<T> data;  private String message;   public String getCode() {    return code;  }   public voID setCode(String code) {    this.code = code;  }   public List<T> getData() {    return data;  }   public voID setData(List<T> data) {    this.data = data;  }   public String getMessage() {    return message;  }   public voID setMessage(String message) {    this.message = message;  }}

  ok,现在还是以上面我们登录的接口为例子开始我们的方法调用,返回的数据格式如图所示

  我们创建UserMenu.java类

package com.qianmo.httprequest.bean; import java.util.List; /** * Created by wangjitao on 2016/12/21 0021. * E-Mail:543441727@qq.com * 用户菜单权限按钮 */public class UserMenu {   /**   * last_login_time : 2016-12-21 15:40:28   * member_ID : 1   * modules : []   * phone : 18900532225   * real_name : 超级管理员   * role : {"role_ID":1,"role_name":"超级管理员"}   * username : superadmin   */   private String last_login_time;  private int member_ID;  private String phone;  private String real_name;  /**   * role_ID : 1   * role_name : 超级管理员   */   private RoleBean role;  private String username;  /**   * module_code : 100   * module_ID : 1   * module_name : 首页   * pID : 0   * type : 1   * value : P_index   */   private List<ModulesBean> modules;   public String getLast_login_time() {    return last_login_time;  }   public voID setLast_login_time(String last_login_time) {    this.last_login_time = last_login_time;  }   public int getMember_ID() {    return member_ID;  }   public voID setMember_ID(int member_ID) {    this.member_ID = member_ID;  }   public String getPhone() {    return phone;  }   public voID setPhone(String phone) {    this.phone = phone;  }   public String getReal_name() {    return real_name;  }   public voID setReal_name(String real_name) {    this.real_name = real_name;  }   public RoleBean getRole() {    return role;  }   public voID setRole(RoleBean role) {    this.role = role;  }   public String getUsername() {    return username;  }   public voID setUsername(String username) {    this.username = username;  }   public List<ModulesBean> getModules() {    return modules;  }   public voID setModules(List<ModulesBean> modules) {    this.modules = modules;  }   public static class RoleBean {    private int role_ID;    private String role_name;     public int getRole_ID() {      return role_ID;    }     public voID setRole_ID(int role_ID) {      this.role_ID = role_ID;    }     public String getRole_name() {      return role_name;    }     public voID setRole_name(String role_name) {      this.role_name = role_name;    }  }   public static class ModulesBean {    private String module_code;    private int module_ID;    private String module_name;    private int pID;    private int type;    private String value;     public String getModule_code() {      return module_code;    }     public voID setModule_code(String module_code) {      this.module_code = module_code;    }     public int getModule_ID() {      return module_ID;    }     public voID setModule_ID(int module_ID) {      this.module_ID = module_ID;    }     public String getModule_name() {      return module_name;    }     public voID setModule_name(String module_name) {      this.module_name = module_name;    }     public int getPID() {      return pID;    }     public voID setPID(int pID) {      this.pID = pID;    }     public int getType() {      return type;    }     public voID setType(int type) {      this.type = type;    }     public String getValue() {      return value;    }     public voID setValue(String value) {      this.value = value;    }  } }

  所以MainActivity代码如下:

package com.qianmo.httprequest; import androID.os.Environment;import androID.os.Handler;import androID.support.v7.app.AppCompatActivity;import androID.os.Bundle;import androID.util.Log;import androID.vIEw.VIEw;import androID.vIEw.VIEw.OnClickListener;import androID.Widget.button;import androID.Widget.Progressbar;import androID.Widget.TextVIEw; import com.qianmo.httprequest.bean.CommonResultBean;import com.qianmo.httprequest.bean.UserMenu;import com.qianmo.httprequest.http.IRequestCallBack;import com.qianmo.httprequest.http.IRequestManager;import com.qianmo.httprequest.http.OkhttpClIEntManager;import com.qianmo.httprequest.http.RequestFactory;import com.qianmo.httprequest.http.ResultCallback;import com.squareup.okhttp.Call;import com.squareup.okhttp.Callback;import com.squareup.okhttp.FormEnCodingBuilder;import com.squareup.okhttp.OkhttpClIEnt;import com.squareup.okhttp.Request;import com.squareup.okhttp.Requestbody;import com.squareup.okhttp.Response; import java.io.file;import java.io.IOException;import java.util.HashMap;import java.util.Map;  public class MainActivity extends AppCompatActivity implements OnClickListener {  private Handler handler;  private TextVIEw tv_message;  private button btn_login;  private Progressbar progressbar;   @OverrIDe  protected voID onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentVIEw(R.layout.activity_main);    tv_message = (TextVIEw) findVIEwByID(R.ID.tv_message);    btn_login = (button) findVIEwByID(R.ID.btn_login);    progressbar = (Progressbar) findVIEwByID(R.ID.progressbar);    handler = new Handler();    btn_login.setonClickListener(this);  }   @OverrIDe  public voID onClick(VIEw vIEw) {    progressbar.setVisibility(VIEw.VISIBLE);      String url = "http://192.168.1.123:8081/API/login";    Map<String,String> params = new HashMap();    params.put("username","superadmin");    params.put("pwd","ba3253876aed6bc22d4a6ff53d8406c6ad864195ed144ab5c87621b6c233b548baeae6956df346ec8c17f5ea10f35ee3cbc514797ed7ddd3145464e2a0bab413");    OkhttpClIEntManager.postAsyn(url,new ResultCallback<CommonResultBean<UserMenu>>() {          @OverrIDe          public voID onError(Request request,Exception e) {           }           @OverrIDe          public voID onResponse(CommonResultBean<UserMenu> response) {            if (response.getData() != null) {              UserMenu userMenu = response.getData();              tv_message.setText(userMenu.getReal_name());              progressbar.setVisibility(VIEw.GONE);            }          }        });   }}

  这样我们就可以简单的调用了,最后看一下我们的效果:

 See You Next Time・・・

 感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

总结

以上是内存溢出为你收集整理的Android OkHttp的简单使用和封装详解全部内容,希望文章能够帮你解决Android OkHttp的简单使用和封装详解所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1147401.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存