okHttp3自用封装

okHttp都已经出到3.2.0了,现在才开始要用到它,感觉自己好low~~

根据平时自己的习惯,还是自己做一下封装,让代码撸起来更加顺畅一点!

okhttp-3.2.0和okio-1.7.0就不多说

首先建一个OkHttpUtils的类

/**
 * HTTP通讯结构处理器
 *
 */
public class OkHttpUtils {

	private static final byte[] LOCKER = new byte[0];
	private static OkHttpUtils mInstance;
	private OkHttpClient mOkHttpClient;

	private OkHttpUtils() {
		okhttp3.OkHttpClient.Builder ClientBuilder=new okhttp3.OkHttpClient.Builder();
		ClientBuilder.readTimeout(30, TimeUnit.SECONDS);//读取超时
		ClientBuilder.connectTimeout(10, TimeUnit.SECONDS);//连接超时
		ClientBuilder.writeTimeout(60, TimeUnit.SECONDS);//写入超时
		mOkHttpClient=ClientBuilder.build();
	}

	public static OkHttpUtils getInstance() {
		if (mInstance == null) {
			synchronized (LOCKER) {
				if (mInstance == null) {
					mInstance = new OkHttpUtils();
				}
			}
		}
		return mInstance;
	}
}



以上的代码和网上其他okhttp3的写法是不一样的。一般网上的代码是下面这样的

mOkHttpClient = new OkHttpClient.Builder()  
.readTimeout(30, TimeUnit.SECONDS)
.connectTimeout(10, TimeUnit.SECONDS) 
.writeTimeout(60, TimeUnit.SECONDS) 
.build();
 
 

为什么要突出这样的变化,和Builder为什么还要把包名的前缀一起写出来尼,主要就是因为OKhttp3中有很多不同类型的Builder,为了后面可以更好的和Map<K, V>结合起来,所以才这么写的

 Request request = new Request.Builder()  
            .url("")  
            .post()  
            .addHeader("", "")
            .build();  


在我现在公司的项目中,我们的接口请求,不管是get还是post,在请求的时候是要用到请求头的,也就是上面 addHeader("", ""),而且还是不止一个请求头,如果像上面那么写的话,那样就很难和Map<K, V>结合起来,所以用写了下面这样的一个方法


        /**
	 * 设置请求头
	 * @param headersParams
	 * @return
	 */
	private Headers SetHeaders(Map<String, String> headersParams){
		Headers headers=null;
		okhttp3.Headers.Builder headersbuilder=new okhttp3.Headers.Builder();
		
		if(headersParams != null)
		{
			Iterator<String> iterator = headersParams.keySet().iterator();
			String key = "";
			while (iterator.hasNext()) {
				key = iterator.next().toString();
				headersbuilder.add(key, headersParams.get(key));
				Log.d("get http", "get_headers==="+key+"===="+headersParams.get(key));
			}
		}
		headers=headersbuilder.build();
		
		return headers;
	}

其中返回的headers其实就是okhttp3提供的okhttp3.Headers,而这个headers是怎么用的尼?其实OKhttp提供添加请求头的方法中,

不止有header("","")和addHeader("","")这两个方法,其实还有一个headers()!有了headers(),前面的header("","")和addHeader("","")这两个方法这两个方法就可以不用了。

同时注意了,这个Builder和最上面的Builder不是同一个类型的,所以在后面的代码中,每一个Builder都是把前面的包名也一起写出来的

Request request = new Request.Builder()  
            .url("")  
            .post() 
            .headers(把上面的SetHeaders()方法返回的headers放到这里就行).build();  

那么,有了上面OKhttp3中添加请求头的方法了,那后面的RequestBody那也就是也一样有的喽,所以下面就写了两个post的方法

第一个:

/**
	 * post请求参数
	 * @param BodyParams
	 * @return
	 */
	private RequestBody SetRequestBody(Map<String, String> BodyParams){
		RequestBody body=null;
		okhttp3.FormBody.Builde formEncodingBuilder=new okhttp3.FormBody.Builder();
		if(BodyParams != null){
			Iterator<String> iterator = BodyParams.keySet().iterator();
			String key = "";
			while (iterator.hasNext()) {
				key = iterator.next().toString();
				formEncodingBuilder.add(key, BodyParams.get(key));
				Log.d("post http", "post_Params==="+key+"===="+BodyParams.get(key));
			}
		}
		body=formEncodingBuilder.build();
		return body;
		
	}

第二个是用来上传图片的:

      /**
	 * Post上传图片的参数
	 * @param BodyParams
	 * @param fileParams
	 * @return
	 */
	private RequestBody SetFileRequestBody(Map<String, String> BodyParams,Map<String, String> fileParams){
		//带文件的Post参数
		RequestBody body=null;
	    <span style="color:#ff0000;">okhttp3.MultipartBody.Builder</span> MultipartBodyBuilder=new okhttp3.MultipartBody.Builder();
	    MultipartBodyBuilder.setType(MultipartBody.FORM);
	    RequestBody fileBody = null;

        if(BodyParams != null){
        	Iterator<String> iterator = BodyParams.keySet().iterator();
        	String key = "";
        	while (iterator.hasNext()) {
        		key = iterator.next().toString();
        		MultipartBodyBuilder.addFormDataPart(key, BodyParams.get(key));
        		Log.d("post http", "post_Params==="+key+"===="+BodyParams.get(key));
        	}
        }
        
		if(fileParams != null){
			Iterator<String> iterator = fileParams.keySet().iterator();
			String key = "";
			int i=0;
			while (iterator.hasNext()) {
				key = iterator.next().toString();
				i++;
				MultipartBodyBuilder.addFormDataPart(key, fileParams.get(key));
				Log.d("post http", "post_Params==="+key+"===="+fileParams.get(key));
				fileBody = RequestBody.create(HttpVariable.Media_Type.MEDIA_TYPE_PNG, new File(fileParams.get(key)));
				MultipartBodyBuilder.addFormDataPart(key, i+".png", fileBody);
			}
		}
		
		
		
		body=MultipartBodyBuilder.build();
		return body;
		
	}

当然,还有一个最简单的get的连接拼接方法了

/**
	 * get方法连接拼加参数
	 * @param mapParams
	 * @return
	 */
	private String setUrlParams( Map<String, String> mapParams){
		String strParams = ""; 
		if(mapParams != null){
			Iterator<String> iterator = mapParams.keySet().iterator();
			String key = "";
			while (iterator.hasNext()) {
				key = iterator.next().toString();
				strParams += "&"+ key + "=" + mapParams.get(key);
			}
		}	
		
		return strParams;
	}


参数和Map<K, V>结合的问题已经解决啦,后面的就是接口数据的问题了,我一般用的json解析工具是gson,所以我写了5个方法来为我以后调用。

第一个是get的调用,调用成功后会自动用gson把返回的json解析成一个实体类的Bean,下面就是这个方法的代码,后面还有调用的方法

      /**
	 * get方法获取实体bean
	 * @param reqUrl UR连接
	 * @param headersParams 请求头参数
	 * @param params 请求参数
	 * @param object 标签
	 * @param mHandler 
	 * @param rspClass 实体类 执行命令获取指定结构 rspClass : 所需转出的结构,例:UserBean.class
	 */
	public void getBeanExecute(String reqUrl,  Map<String, String> headersParams, Map<String, String> params,
			Object object,final Handler mHandler, final Class<?> rspClass){
		
		okhttp3.Request.Builder RequestBuilder=new okhttp3.Request.Builder();
		RequestBuilder.url(reqUrl+setUrlParams(params));//添加URL地址
		RequestBuilder.headers(SetHeaders(headersParams));//添加请求头
		RequestBuilder.tag(object);//添加请求标签
		Request request=RequestBuilder.build();
		Log.d("get http", "get_url==="+request.url());
		
		
		Call call = mOkHttpClient.newCall(request);
		call.enqueue(new Callback() {
			@Override
			public void onFailure(Call arg0, IOException arg1) {
				// TODO Auto-generated method stub
				Log.d("get http", "get_onFailure==="+arg1.toString());
				Message mess = mHandler.obtainMessage();//
				mess.what = 404;
				mess.obj = "通讯错误-020";
				mHandler.sendMessage(mess);
			}

			@Override
			public void onResponse(Call arg0, Response arg1) throws IOException {
				// TODO Auto-generated method stub
				Log.d("get http", "get_code==="+arg1.code());
				String Result = "";
				Message mess = mHandler.obtainMessage();
				if (arg1.code() == 200) {
					Result = arg1.body().string();
					Log.d("get http", "get==="+Result);
					try {
						Gson gson = new Gson();
						// 转换返回结果信息
						JsonBean jsonBean = new JsonBean();
						JSONObject jsonObject = new JSONObject(Result.toString());
						jsonBean.setMsg(jsonObject.optString("msg"));
						jsonBean.setCode(jsonObject.optString("code"));
						String strData = "";
						Object dataBean = null;
						if (jsonBean.getCode().equals(HttpVariable.ERROR_CODE.SUCCESS)) {
							jsonBean.setResult(jsonObject.optString("result"));
							if (!TextUtils.isEmpty(jsonBean.getResult())) {
								if (jsonBean.getResult().substring(0, 1).equals("[")) {
									String srt = jsonBean.getResult();
									strData = srt.substring(1, srt.length() - 1);
								} else {
									strData = jsonBean.getResult();
								}
							}
							dataBean = rspClass.newInstance();
							if (!TextUtils.isEmpty(strData)) {
								dataBean = gson.fromJson(strData, rspClass);
							}
						}

						if (jsonBean.getCode().equals(HttpVariable.ERROR_CODE.SUCCESS)) {
							mess.what = Integer.valueOf(jsonBean.getCode());
							if (!TextUtils.isEmpty(strData)) {
								mess.obj = dataBean;
							} else {
								mess.obj = jsonBean.getMsg();
							}
						} else {
							mess.what = Integer.valueOf(jsonBean.getCode());
							mess.obj = jsonBean.getMsg();
						}
					} catch (Exception e) {
						mess.what = 404;
						mess.obj = "数据异常-021";
					}
				} else {
					mess.what = arg1.code();
					mess.obj = "通讯异常-"+arg1.code();
				}
				mHandler.sendMessage(mess);
			}
		});
	}

{"code":"0","msg":"成功","result":{"aqi":39,"area":"广州","pm2_5":22,"quality":"优","weather":"晴","temperature_min":"21","temperature_max":"31"}}

这是接口拿到的数据

看到这样的数据结构,我就会先建一个wrather的实体类bean

import java.io.Serializable;

/**
 * 天气Bean
 * @author Kevin
 *
 */
public class WeatherBean implements Serializable{
	
	private static final long serialVersionUID = 1L;
	
	/**
	 *  aqi 空气质量指数 字符串     
		area 区域 字符串     
		pm2_5 pm2.5       
		quality 空气质量       
		level 空气质量等级       
		weather 天气描述       
		temperature_now 当前温度       
		temperature_min 最低温度       
		temperature_max 最高温度   
	 */
	
	private String aqi;
	private String area;
	private String pm2_5;
	private String quality;
	private String level;
	private String weather;
	private String temperature_now;
	private String temperature_min;
	private String temperature_max;
	
	
	public String getAqi() {
		return aqi;
	}
	public void setAqi(String aqi) {
		this.aqi = aqi;
	}
	public String getArea() {
		return area;
	}
	public void setArea(String area) {
		this.area = area;
	}
	public String getPm2_5() {
		return pm2_5;
	}
	public void setPm2_5(String pm2_5) {
		this.pm2_5 = pm2_5;
	}
	public String getQuality() {
		return quality;
	}
	public void setQuality(String quality) {
		this.quality = quality;
	}
	public String getLevel() {
		return level;
	}
	public void setLevel(String level) {
		this.level = level;
	}
	public String getWeather() {
		return weather;
	}
	public void setWeather(String weather) {
		this.weather = weather;
	}
	public String getTemperature_now() {
		return temperature_now;
	}
	public void setTemperature_now(String temperature_now) {
		this.temperature_now = temperature_now;
	}
	public String getTemperature_min() {
		return temperature_min;
	}
	public void setTemperature_min(String temperature_min) {
		this.temperature_min = temperature_min;
	}
	public String getTemperature_max() {
		return temperature_max;
	}
	public void setTemperature_max(String temperature_max) {
		this.temperature_max = temperature_max;
	}
	
}

调用的方法如下:

//这里可以写在单独一个接口类里面,在Activity中直接用一行代码来调用这个方法,这样就不会把代码复杂货
Map<String, String> headersdatas = new HashMap<String, String>();//这里是添加你的请求头参数
		headersdatas.put("", "");
		headersdatas.put("", "");
		headersdatas.put("", "");
		
		
Map<String, String> datas = new HashMap<String, String>();//这里是拼接的请求参数
		datas.put("", "");
		datas.put("", "");
		datas.put("", "");		
		
OkHttpUtils.getInstance().getBeanExecute("你的接口url", headersdatas, datas,this, mHandler,WeatherBeanclass);
/**
	 * 获取天气信息
	 */
	private Handler mHandler=new Handler(){
		@Override
		public void handleMessage(Message msg) {
			// TODO Auto-generated method stub
			if (msg.what==0) {//请求成功
				try { 
					WeatherBean weatherBean=new WeatherBean();
					weatherBean=(WeatherBean) msg.obj;//拿到接口返回的天气的实体类
					.....//这里省略的代码就是数据拿到后操作UI部分
				} catch (Exception e) {
					// TODO: handle exception
				}
			}else{
				LogOut.showToast(getApplicationContext(), (String) msg.obj);
			}
		}
	};


 

还剩下的直接get获取实体类列表和post的方法和上面的类似。。所以笔记就先写到这里喽。。。





  • 9
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 10
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值