简单的封装okhttp

由于公司的项目需要上传文件,利用阿里的oss存储,整个过程比较麻烦。对于网络访问就简单的用okhttp封装了一些需要的方法,比较简单。
主要从ok的两点入手,一是ok获取网络结果是在子线程,无法直接更新比较麻烦,另外就是参数将结果解析。
直接上代码
创建httpmanager类,官方文档都说了最好使用单例,所以我们也就不对着干了。
官网地址:http://square.github.io/okhttp/
此处需要注意在2.x版本时,时间时间等设置与3.x版本不一样,如果还像2.x版本设置是没有效果的差异如下:

          //创建OkHttpClient的实例
// okHttpClient = new OkHttpClient();  2.0版本构建类的模式okHttpClient = new OkHttpClient.Builder()//3.x版本构建类的模式
                .readTimeout(30, TimeUnit.SECONDS)
                .connectTimeout(30, TimeUnit.SECONDS)
               /* .readTimeout(1, TimeUnit.MINUTES)
                .connectTimeout(1, TimeUnit.MINUTES)*/
                .build();//3.0后最新编辑模式

整体上就不说了直接贴上代码:

public class HttpManager {

    private static HttpManager mHttpManager;
//    private final OkHttpClient okHttpClient;
    private final Gson gson;
    private final Handler handler;
    private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");//post请求编码
    private final OkHttpClient okHttpClient;

    private String mNppcodes="abcd";


    public HttpManager() {
        //创建OkHttpClient的实例
//        okHttpClient = new OkHttpClient();  2.0版本构建类的模式
        okHttpClient = new OkHttpClient.Builder()//3.x版本构建类的模式
                .readTimeout(30, TimeUnit.SECONDS)
                .connectTimeout(30, TimeUnit.SECONDS)
               /* .readTimeout(1, TimeUnit.MINUTES)
                .connectTimeout(1, TimeUnit.MINUTES)*/
                .build();//3.0后最新编辑模式
        //解析JSON
        gson = new Gson();
        //子线程中更新Ui用到Handler
        handler = new Handler(Looper.getMainLooper());
    }

    //单例
    public static HttpManager getHttpManager() {
        if (mHttpManager == null) {
            synchronized (HttpManager.class) {
                if (mHttpManager == null) {
                    mHttpManager=new HttpManager();
                }
            }
        }
        return mHttpManager;
    }

    /**
     * get请求
     * @param url
     * @param baseCallBack
     */
    public void get(String url,BaseCallBack baseCallBack,String token){
        Request request=buildRequest(url, RequestTyep.GET,token);
        doRequest(request,baseCallBack);
    }

    /**
     * post请求
     * @param url
     * @param baseCallBack
     */
    public void postJson(String url,Object json ,String token,BaseCallBack baseCallBack){
        Gson gson = new Gson();
        String gsonString = gson.toJson(json);
        Request.Builder build=new Request.Builder();
                build
                .post(buildRequestJsonBody(gsonString))
                .url(url)
                .addHeader("C_AT_",token)
                .addHeader("nppCode",mNppcodes);
        Request request = build.build();
        doRequest(request,baseCallBack);
    }

/*
* 并且返回时间差
* */
    public void postJsonAndGet(String url, Object json , String token, BaseCallBack baseCallBack, Context context){
        Gson gson = new Gson();
        String gsonString = gson.toJson(json);
        Request.Builder build=new Request.Builder();
                build
                .post(buildRequestJsonBody(gsonString))
                .url(url)
                .addHeader("C_AT_",token)
                .addHeader("nppCode",mNppcodes);
        Request request = build.build();
        doRequestForgettime(request,baseCallBack,context);
    }


    /*同步post请求
    * */
    public String executepostJson(String url,String json ,String token)  {
        Request.Builder build=new Request.Builder();
        build.post(buildRequestJsonBody(json))
                .url(url)
                .addHeader("C_AT_",token)
                .addHeader("nppCode",mNppcodes);
        Request request = build.build();

        return doExecuteRequest(request);
    }

/**
 * postJson的body
 */
    private RequestBody buildRequestJsonBody(String json) {
        RequestBody body = RequestBody.create(JSON,json);
        return body;
    }

    /**
     * 创建Request//请求头也可以分装在此
     * @return
     */
    private Request buildRequest(String url, RequestTyep type, String token) {
        Request.Builder build=new Request.Builder();
        if (type== RequestTyep.GET){
            build.get();
        }else if (type== RequestTyep.POST){
            build.post(buildRequestBody());
        }
        build.url(url)
            .addHeader("C_AT_",token);
        return build.build();
    }

    /**
     * 创建post请求体
     * @return
     */
    private RequestBody buildRequestBody() {
        FormBody.Builder builder=new FormBody.Builder();
        return builder.build();
    }

    /**
     * 请求类型
     */
    enum RequestTyep{
        GET,
        POST,
        POSTJSON
    }

    private String doExecuteRequest(Request request) {
        Response response = null;
        try {
            response = okHttpClient.newCall(request).execute();
            if (response.isSuccessful()) {
                String string = response.body().string();
                return string;
            } else {
                LogUtils.wyjlog("false");
                return "";
            }
        } catch (IOException e) {
            e.printStackTrace();
            return "";
        }
    }

    /**
     * okHttp post同步请求
     */
    private String  executePost (String url,String json) {
        try {
            Gson gson = new Gson();
            String gsonString = gson.toJson(json);
            Request.Builder build=new Request.Builder();
            build .post(buildRequestJsonBody(gsonString))
                    .url(url).addHeader("C_AT_",token)
                    .addHeader("nppCode",mNppcodes);
            Request request = build.build();
            final Call call = okHttpClient.newCall(request);//创建一个Call
            Response response = call.execute(); //执行请求
            if (response.isSuccessful()) { //请求执行成功
                LogUtils.wyjlog("response ----->" + response.body().string());
                return response.body().string();
            } else {
                return "";
            }
        } catch (Exception e) {
            return "";
        }
    }

    private void doRequest(Request request, final BaseCallBack baseCallBack){
//        okHttpClient.newCall().execute();
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                senFailure(baseCallBack,call, e,"未连接上服务器"+e.getMessage());
            }
            @Override
            public void onResponse(Call call, Response response) throws IOException {
                boolean successful = response.isSuccessful();
                if (successful){
                    String json = response.body().string();
                    sendSuccess(baseCallBack,call,json);
                }else {
                    int code=response.code();
                    ResponseBody body = response.body();
                    String string = body.string();
                    senFailure(baseCallBack,call,null,code+"----"+string);
                }
            }
        });
    }

    private void doRequestForgettime(Request request, final BaseCallBack baseCallBack, final Context context){
//        okHttpClient.newCall().execute();
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                senFailure(baseCallBack,call, e,"未连接上服务器"+e.getMessage());
            }
            @Override
            public void onResponse(Call call, Response response) throws IOException {
                boolean successful = response.isSuccessful();
                Headers headers = response.headers();
                long clientTime = getDeltaBetweenServerAndClientTime(headers);//utc时间显示
                LogUtils.wyjlog("clientTime"+clientTime);
                SpUtils.saveString(context, SpConstant.TIMEESCAPE,clientTime+"");
                if (successful){
                    String json = response.body().string();
                    sendSuccess(baseCallBack,call,json);
                }else {
                    int code=response.code();
                    ResponseBody body = response.body();
                    String string = body.string();
                    senFailure(baseCallBack,call,null,code+"----"+string);
                }
            }
        });
    }

    /**
     * 获取差值
     **/
    private long getDeltaBetweenServerAndClientTime(Headers headers) {
        long deltaBetweenServerAndClientTime=0;
        if (headers!=null) {
            final String strServerDate = headers.get("Date");
            if (!TextUtils.isEmpty(strServerDate)){
//                final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss 'GMT'", Locale.CHINA);
                final SimpleDateFormat simpleDateFormat =new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss 'GMT'", Locale.ENGLISH);
                TimeZone.setDefault(TimeZone.getTimeZone("GMT+8"));
                try {
                    Date serverDate  = simpleDateFormat.parse(strServerDate);
                    deltaBetweenServerAndClientTime = serverDate.getTime()-new Date().getTime()+8*60*60*1000;
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            }
        }
        return deltaBetweenServerAndClientTime;
    }

    /**
     * 请求成功的处理
     * @param baseCallBack
     * @param call
     * @param json
     */
    private void sendSuccess(final BaseCallBack baseCallBack, final Call call, final String json) {
        handler.post(new Runnable() {
            @Override
            public void run() {
                if (baseCallBack.type==String.class){
                    try {
                        baseCallBack.onSuccess(call,json);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }else {
                    Object object = gson.fromJson(json, baseCallBack.type);
                    try {
                        baseCallBack.onSuccess(call,object);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        });
    }
    /**
     * 请求失败的处理
     * @param baseCallBack
     * @param call
     *
     */
    private void senFailure(final BaseCallBack baseCallBack, final Call call, final IOException e, final String code) {
        handler.post(new Runnable() {
            @Override
            public void run() {
                baseCallBack.onFailure(call,e);
                LogUtils.wyjlog("网络请求状态:"+code);
            }
        });
    }
}

然后根据更新的需求:在主线程中更新,创建了一个BaseCallBack抽象类:


/**
 * @创建者 wyj
 * @创建时间 2017/4/514:09.
 * @描述  回调
 * @更新者 ${author}
 * @更新时间 2017/4/514:09.
 */
public abstract class BaseCallBack<T>  {

    Type type;
    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]);
    }

    public BaseCallBack()
    {
        type = getSuperclassTypeParameter(getClass());
    }

    public abstract void onFailure(Call call, IOException e);

    public abstract void onSuccess(Call call, T t) throws Exception;
}

还有些其他的用法可参看文章:
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0106/2275.html

### 封装 OkHttp 的最佳实践 为了简化 Android 应用中的网络请求操作,可以创建一个通用的 `OkHttpClient` 实例并封装常用的请求方法。这不仅提高了代码的可维护性和重用率,还使得错误处理更加集中化。 #### 创建全局 OkHttpClient 单例实例 通过定义一个应用程序级别的类来保存单例模式下的 `OkHttpClient` 对象,可以在整个应用生命周期内重复利用这个对象而无需每次都重新初始化它[^3]: ```java // MyApp.java package com.example.myapp; import android.app.Application; import okhttp3.OkHttpClient; public class MyApp extends Application { private static OkHttpClient okHttpClient; @Override public void onCreate() { super.onCreate(); // 初始化 OkHttpClient 并设置默认配置项 okHttpClient = new OkHttpClient.Builder() .connectTimeout(15, java.util.concurrent.TimeUnit.SECONDS) .readTimeout(15, java.util.concurrent.TimeUnit.SECONDS) .writeTimeout(15, java.util.concurrent.TimeUnit.SECONDS) .build(); } public static OkHttpClient getOkHttpClient(){ return okHttpClient; } } ``` #### 构建统一接口服务层 接着构建一个用于发起各种类型的 HTTP 请求的服务类,比如 GET 和 POST 方法。这里展示了一个简单的实现方式,其中包含了同步和异步两种调用形式[^1]: ```java // HttpService.java package com.example.myapp.network; import android.os.AsyncTask; import androidx.annotation.NonNull; import okhttp3.Call; import okhttp3.Callback; import okhttp3.Request; import okhttp3.Response; import org.json.JSONObject; import java.io.IOException; public final class HttpService { /** * 发起GET请求 (异步) */ public static void doGetAsync(@NonNull String url, Callback callback){ Request request = new Request.Builder().url(url).build(); Call call = MyApp.getOkHttpClient().newCall(request); call.enqueue(callback); // 异步执行 } /** * 发起POST请求 (带JSON参数) (异步) */ public static void doPostJsonAsync(@NonNull String url, JSONObject jsonParams, Callback callback)throws Exception{ // ... 设置RequestBody ... // 使用jsonParams构建post body... RequestBody requestBody = RequestBody.create( MediaType.parse("application/json; charset=utf-8"), jsonParams.toString()); Request request = new Request.Builder() .url(url) .post(requestBody) .build(); Call call = MyApp.getOkHttpClient().newCall(request); call.enqueue(callback); // 异步执行 } /** * 同步获取数据的方法可用于某些特定场景下, * 如在子线程中直接阻塞等待响应结果而不影响主线程体验。 */ public static Response doGetSync(String url) throws IOException { Request request = new Request.Builder().url(url).build(); try(Response response = MyApp.getOkHttpClient().newCall(request).execute()){ if (!response.isSuccessful()) throw new RuntimeException("Unexpected code " + response); return response; } } // 更多其他HTTP动词的支持... } ``` 上述代码片段展示了如何基于 OkHttp 进行基本功能的封装,包括但不限于发送 GET/POST 请求以及处理相应的回调逻辑。对于更复杂的应用需求,则可以根据实际情况进一步扩展此框架的功能集。 #### 错误与异常处理机制设计 考虑到网络环境不稳定等因素,在封装过程中应当充分考虑可能出现的各种异常情况,并提供合理的反馈给上层业务模块。通常做法是在每个 API 调用处捕获可能发生的 IO 或者解析失败等问题,并将其转换成易于理解的消息传递出去[^2]。 例如,在上面的例子中可以通过自定义 `Callback` 接口的方式向外部暴露成功与否的状态信息;而在同步版本里则可以直接抛出受检异常让调用方自行决定后续动作。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值