Android工作笔记之okHttp,Xutils等框架的2次封装实例

表现形式:实体类->第三方框架->服务器返回的jso字符串代表的实体类

  优点:用实体类代表请求参数,可以建请求基类。方便管理,且可把网络请求都放一个文件中,避免大量无用代码

  缺点:用了反射。其他未知

1.最终表现形式此处是封装okhttp

private void start() {
        JiuDianbin bin=new JiuDianbin();
        bin.Environment="2";
        bin.RegionId=1;
        NetCenter.getHotelList(bin, Resonse_HotelList.class, new OkttpUtils.MResponse() {
            @Override
            public void success(Object object) {
                   Resonse_HotelList hotelList= (Resonse_HotelList) object;
                   if(hotelList.Hotels.size()!=0){
                       HotelBin hotelBin = hotelList.Hotels.get(0);
                       text.setText(hotelBin.Address);
                   }
            }

            @Override
            public void faild(String string) {
                Log.i("http",string);
            }

            @Override
            public void error(String string) {
                Log.i("http",string);
            }
        });
    }
备注:jiudianbin 是请求的实体类,有2个属性, Resonse_HotelList是网络接口返回的数据的实体类,第三个参数是自定义的一个回调接口。
2.android所有网络请求的方法放在一个文件中 便于管理

public class NetCenter {
    /**
     * 获取酒店信息
     */
    public static<T extends ResponseBaseBin>  void getHotelList(Object bin, final Class<T> tClass, final
    OkttpUtils.MResponse mresponse){
        String url = "xxxxxxxxxxxxxxxxx";
        OkttpUtils.sendPost(url,bin,tClass,mresponse);
    }
}
备注;此处多了一个url,存放一个项目中所有的网络请求, ResponseBaseBin是所有网络接口返回的数据的基类,所有的json数据的类 都是继承他,此处有2个属性

  一个是状态码一个是消息,当状态码为1时代表成功,为2时代表失败,此处是和后台协商返回的状态码。

StatusCode 和 StatusMessage

3,下面是主要封装的代码

步骤1:首先得把传进来的第二个参数,请求的类,转换成第三方框架需要的类,此处转成okttp需要的RequestBody

步骤2:根据网络请求参数和url,网络请求

步骤3:根据传进来的第三个参数tClass使用Gson转换json数据

步骤4:把转换好的数据传递给回调接口。

步骤5:根据实际情况,此处OKttp返回的数据的接口在子线程,需要进入主线程(很多框架最后都不需要这一步)

下面是具体代码:

package com.example.com.okhttp;

import android.os.Handler;
import android.util.Log;

import com.google.gson.Gson;

import java.io.IOException;

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

/**
 * Created by 胡楠奇 on 2016/12/8.
 */

public class OkttpUtils {
    private static Handler handler=new Handler();
    public static <T extends ResponseBaseBin> void sendPost(String url, Object bin, final Class<T> tClass, final
    MResponse mresponse) {
        Log.i("http","请求地址:"+url);
        OkHttpClient httpClient = new OkHttpClient();
        RequestBody requestBody = ZOkHttpFrom.getRequestBody(bin.getClass(), bin);
        Request request=new Request.Builder().url(url).post(requestBody).build();
        httpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {//这里是网址找不到就会进入
                final String s = e.toString();
                       handler.post(new Runnable() {
                           @Override
                           public void run() {
                               mresponse.error(s);
                           }
                       });
            }
            @Override
            public void onResponse(Call call, final Response response) throws IOException {
                final String errocode = response.toString();
                if(response.isSuccessful()){
                     String json = response.body().string();
                     Log.i("http","返回数据:"+json);
                     Gson gson=new Gson();
                     final T t = gson.fromJson(json, tClass);
                     if(t.StatusCode==1){//这里根据实际情况,此处是后台返回1成功,
                         handler.post(new Runnable() {//进入主线程
                             @Override
                             public void run() {
                                 mresponse.success(t);
                             }
                         });
                     }else{
                         handler.post(new Runnable() {
                             @Override
                             public void run() {
                                 mresponse.faild(t.StatusMessage);
                             }
                         });
                     }
                 }else{//这里代表服404等错误
                     handler.post(new Runnable() {
                         @Override
                         public void run() {
                             mresponse.error(errocode);
                         }
                     });
                 }
            }
        });
    }

    interface MResponse {
        /**
         * 请求成功返回,返回状态码显示成功
         * @param object
         */
        void success(Object object);

        /**
         * 请求成功,返回的状态码显示失败
         * @param string
         */
        void faild(String string);

        /**
         * 网络请求错误,包括链接无效,404等
         * @param string
         */
        void error(String string);
    }
}
4.转换实体类的方法

主要是通过反射然后来将自定义实体类转换成需要的实体类

Field[] field  = clazz.getFields()
获取所有属性,然后全部转化成字符串

public  static RequestBody getRequestBody(Class<?> clazz, Object object){
        HashMap<String,Object> data=getValuesHash(clazz,object);
        FormBody.Builder builder = new FormBody.Builder();
        Iterator<Map.Entry<String,Object>> iter = data.entrySet().iterator();
        StringBuilder post=new StringBuilder();
        while (iter.hasNext()) {
            Map.Entry<String,Object> entry = (Map.Entry<String,Object>) iter.next();
            Object value=entry.getValue();
            if(TextUtils.isEmpty(String.valueOf(value))||TextUtils.isEmpty(entry.getKey())){
                continue;
            }
            builder.add(entry.getKey(),String.valueOf(value));
            post.append(entry.getKey()+"="+String.valueOf(value)+"&");
        }
        Log.i("http","post数据:"+post.toString());
        return builder.build();
    }
备注:此处显示获取所有属性存储在hashmap中,然后把map里面的数据全部添加到 RequestBody 中,

5.注意各种log,最终调试时会输出,请求地址,请求参数,返回数据,方便调试,还可以自定log,控制开关,正式版的时候关闭就行

6.此处封装的pos请求,表单,其他的第三方框架都差不多可以这样。

7.完成后就能像第一步一样,建立一个请求类,建立一个返回的数据的类,然后方便的进行网络请求了,请求类如果有必要也可以建立一个基类方便管理修改




 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值