OkHttp

OkHttp工具类封装相关资源
博客提供了OkHttp相关资源链接https://github.com/square/okhttp ,涉及OkHttp在安卓开发中的工具类封装,OkHttp是安卓开发常用的网络请求库,工具类封装可提高开发效率。

https://github.com/square/okhttp

package com.yaoxin.doctor.httpservice;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.text.TextUtils;
import android.util.Log;

import com.yaoxin.doctor.bean.PublicIp;
import com.yaoxin.doctor.interFace.ReqCallBack;
import com.yaoxin.doctor.utils.SharePreferenceUtil;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

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

import static java.lang.String.valueOf;

/**
 * 基于okhttp-3.10.0.jar进行二次封装的网络请求类
 * <p>
 * OkHttpClient:客户端对象
 *
 * @author Eleven
 */
@SuppressLint("DefaultLocale")
public class MyOkHttp extends OkHttpClient {

    private static final String URL_PREFIX_HTTP = "http";
    private static final String RESULT_SUCCESS = "0";
    private static final String PLATFORM = "platform";
    private static final String TOKEN = "token";
    private static final String DID = "did";
    private static final String PARAM_VERSION = "version";
    private static final String MSG_NETWORK_ERROR = "网络错误";
    private static final String MSG_CDCARD_ERROR = "文件下载出错";

    private static volatile MyOkHttp mInstance;// 单利引用
    private OkHttpClient mOkHttpClient;// okHttpClient 实例
    private Handler okHttpHandler;// 全局处理子线程和M主线程通信
    private static final String TAG = "MyOkHttp";

    /**
     * 初始化MyOkHttp
     */
    public MyOkHttp(Context context) {
        // TODO Auto-generated constructor stub
        // 初始化OkHttpClient
        mOkHttpClient = new OkHttpClient().newBuilder()
                .connectTimeout(10, TimeUnit.SECONDS)// 设置超时时间
                .readTimeout(10, TimeUnit.SECONDS)// 设置读取超时时间
                .writeTimeout(10, TimeUnit.SECONDS)// 设置写入超时时间
                .addInterceptor(new LogInterceptor())
                .build();
        // 初始化Handler
        okHttpHandler = new Handler(context.getMainLooper());

    }

    /**
     * 获取单例引用
     *
     * @return
     */
    public static MyOkHttp getInstance(Context context) {
        if (mInstance == null) {
            synchronized (MyOkHttp.class) {
                mInstance = new MyOkHttp(context);
            }
        }
        return mInstance;
    }

    // MyOkHttp.requestGetBySyn
    // 请求药信API GET接口,并将正确的返回值缓存到本地文件
    // 参数:
    // url - 接口地址
    // target - 缓存文件名(自动添加缓存路径)
    // callback - 回调
    // 说明:
    // - 自动实例化,调用者只需使用Utils.requestGetBySyn(...)即可调用
    // - target中自动添加.json后缀(防止疏忽)
    // - 自动添加uid与version参数到url,调用者url中无需包含
    // - 已自动对返回值进行了错误判断,返回值不是JSON,或接口中返回“错误”,均自动进入onFailure处理,
    // 调用者无需在onSuccess中对返回值再次进行解析判断,直接拿取数据处理即可
    // - 若接口返回错误(包括即便是正确的JSON,但接口中返回“错误”的情况),均不会进行本地缓存,
    // 即某一次的错误数据不会覆盖原有正确的缓存数据
    // - onSuccess处理中,可直接使用获取结果字符串,无需再通过读取缓存文件获取结果
    // - onFailure处理中,可直接使用msg参数获取错误字符串进行后续处理
    public static <T> Call requestGetBySyn(Context context, String url,
                                           String target, ReqCallBack<T> callBack) {
        return MyOkHttp.getInstance(context).requestGetByAsyn(context, url,
                target, callBack);

    }

    // MyOkHttp.requestPostBySyn
    // 请求药信API POST接口,
    // 参数:
    // url - 接口地址(自动添加5iyaoxin前缀)
    // map - 上传数据
    // callback - 回调
    // 说明:
    // - 自动实例化,调用者只需使用MyOkHttp.requestPostBySyn(...)即可调用
    // - 已自动对返回值进行了错误判断,返回值不是JSON,或接口中返回“错误”,均自动进入onFailure处理,
    // 调用者无需在onSuccess中对返回值再次进行解析判断,直接拿取数据处理即可
    // 某一次的错误数据不会覆盖原有正确的缓存数据
    // - onSuccess处理中,可直接使用获取结果字符串,无需再通过读取缓存文件获取结果
    // - onFailure处理中,可直接使用msg参数获取错误字符串进行后续处理
    public static <T> Call requestPostBySyn(Context context, String url,
                                            Map<String, Object> map, ReqCallBack<T> callBack) {
        return MyOkHttp.getInstance(context).requestPostByAsyn(context, url,
                map, callBack);

    }

    // MyOkHttp.requestPostFileBySyn
    // 请求药信API POST接口上传文件
    // 参数:
    // url - 接口地址(自动添加5iyaoxin前缀)
    // map - 上传文件
    // map - 上传数据
    // callback - 回调
    // 说明:
    // - 自动实例化,调用者只需使用MyOkHttp.requestPostFileBySyn(...)即可调用
    // - 已自动对返回值进行了错误判断,返回值不是JSON,或接口中返回“错误”,均自动进入onFailure处理,
    // 调用者无需在onSuccess中对返回值再次进行解析判断,直接拿取数据处理即可
    // 某一次的错误数据不会覆盖原有正确的缓存数据
    // - onSuccess处理中,可直接使用获取结果字符串,无需再通过读取缓存文件获取结果
    // - onFailure处理中,可直接使用msg参数获取错误字符串进行后续处理
    public static <T> Call requestPostFileBySyn(Context context, String url,
                                                File file, Map<String, Object> map, ReqCallBack<T> callBack) {
        return MyOkHttp.getInstance(context).requestPostByFileAsyn(context,
                url, file, map, callBack);

    }

    // MyOkHttp.doDownloading
    // 下载指定url的文件到缓存路径(自动添加http前缀)
    // 参数:
    // url - 文件地址
    // target - 缓存文件名(自动添加缓存路径)
    // callback - 回调
    // 说明:
    // - 自动实例化,调用者只需使用MyOkHttp.doDownloading(...)即可调用
    // - url中无需包含http://部分
    public static <T> Call doDownloading(Context context, String url,
                                         String target, ReqCallBack<T> callBack) {
        return MyOkHttp.getInstance(context).downLoad(context, url, target,
                callBack);
    }

    /**
     * okHttp get异步请求
     *
     * @param url      接口地址
     * @param target   缓存名字
     * @param callBack 请求返回数据回调
     * @param <T>      数据泛型
     * @return
     */
    @SuppressWarnings("unchecked")
    private <T> Call requestGetByAsyn(final Context context, String url,
                                      String target, final ReqCallBack<T> callBack) {

        try {
            if (!url.startsWith(PublicIp.URL)
                    && !url.startsWith(URL_PREFIX_HTTP)) {
                url = PublicIp.URL + url;
            }
            // 去判断是否有用户号和版本号
            url = getUrlWithExtras(context, url);
            if (!TextUtils.isEmpty(target)) {
                // 检查缓存名称是否合格
                if (!target.toLowerCase().endsWith(".json")) {
                    target = target + ".json";
                }
                // 检查缓存名称是否包含路径
                if (!target.startsWith(context.getFilesDir().getAbsolutePath())) {
                    target = getCacheFileName(target, context);
                }
            }
            url = url.replace(" ","");
            final String targetFileName = target;

            final Request request = new Request.Builder().get().url(url)
                    .build();
            final Call call = mOkHttpClient.newCall(request);

            if (PublicIp.URL.contains("test")) {
                Log.i(TAG, "requestGetByAsyn: " + url);
            }

            call.enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                    Log.i(TAG, "onFailure: " + e.toString());
                    boolean isDestoryed = false;
                    try {
                        Activity activity = (Activity) context;
                        if (activity.isFinishing()) {
                            isDestoryed = true;
                        }
                    } catch (Exception e1) {
                        // TODO: handle exception
                    }
                    if (isDestoryed) {
                        return;
                    }
                    if (!call.isCanceled()) {
                        failedCallBack(MSG_NETWORK_ERROR, callBack);
                    }
                }

                @Override
                public void onResponse(Call call, Response response)
                        throws IOException {
                    boolean isDestoryed = false;
                    try {
                        Activity activity = (Activity) context;
                        if (activity.isFinishing()) {
                            isDestoryed = true;
                        }
                    } catch (Exception e) {
                        // TODO: handle exception
                    }
                    if (isDestoryed) {
                        return;
                    }
                    if (response.isSuccessful()) {
                        // 接口成功拿到数据
                        String result = response.body().string();
                        Log.i(TAG, "onResponse: " + result);
                        /**
                         * logout代码
                         */
                        // 辨别接口返回标识码
                        String error = getErrorOfReponseString(result);
                        if (TextUtils.equals(error, "信息错误!")) {

                        }
                        if (error.equals(RESULT_SUCCESS) && callBack != null) {
                            // 自动缓存数据以.json的文件存储
                            saveContentToFile(result, targetFileName);
                            // 成功回调
                            successCallBack((T) result, callBack);
                        } else {
                            String errorMsg = "";
                            try {
                                JSONObject obj = new JSONObject(result);
                                if (obj.has("msg")) {
                                    errorMsg = obj.getString("msg");
                                }
                            } catch (JSONException e) {
                                e.printStackTrace();
                            }
                            failedCallBack(errorMsg, callBack);
                        }

                    } else {
                        String result = response.body().string();
                        Log.i(TAG, "onResponse: " + result);
                        failedCallBack(MSG_NETWORK_ERROR, callBack);
                    }
                }

            });
            return call;
        } catch (Exception e) {
            return null;
        }

    }

    /**
     * okHttp post异步请求
     *
     * @param url      接口地址
     * @param map      上传数据
     * @param callBack 请求返回数据回调
     * @param <T>      数据泛型
     * @return
     */
    @SuppressWarnings({"unchecked"})
    private <T> Call requestPostByAsyn(Context context, String url,
                                       Map<String, Object> map, final ReqCallBack<T> callBack) {

        try {
            if (!url.startsWith(PublicIp.URL)
                    && !url.startsWith(URL_PREFIX_HTTP)) {
                url = PublicIp.URL + url;
            }
            // 去判断是否有用户号和版本号
            url = getUrlWithExtras(context, url);

//            MultipartBody.Builder requestBody = new MultipartBody.Builder().setType(MultipartBody.FORM);
            FormBody.Builder requestBody = new FormBody.Builder();
            if (map != null) {
                // map 里面是请求中所需要的 key 和 value
                for (Map.Entry entry : map.entrySet()) {
                    requestBody.add(valueOf(entry.getKey()), valueOf(entry.getValue()));
                }
//                requestBody.add(PARAM_VERSION, getVersion(context));
//                requestBody.add(PLATFORM, "Android");
//                requestBody.add(TOKEN, "token");
//                requestBody.add(DID, getUserId(context));
            }
            final Request request = new Request.Builder().post(requestBody.build())
                    .url(url).build();
            final Call call = mOkHttpClient.newCall(request);
            call.enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {

                    failedCallBack(MSG_NETWORK_ERROR, callBack);

                }

                @Override
                public void onResponse(Call call, Response response)
                        throws IOException {
                    Log.e(TAG, "onResponse: "+response.message().toString() );
                    if (response.isSuccessful()) {
                        // 接口成功拿到数据
                        String result = response.body().string();
                        // 辨别接口返回标识码
                        String error = getErrorOfReponseString(result);
                        if (error.equals(RESULT_SUCCESS) && callBack != null) {
                            // 成功回调
                            successCallBack((T) result, callBack);
                        } else {
                            failedCallBack(error, callBack);
                        }

                    } else {
                        failedCallBack(MSG_NETWORK_ERROR, callBack);
                    }
                }

            });
            return call;
        } catch (Exception e) {
            return null;
        }

    }

    /**
     * okHttp post异步请求
     *
     * @param url      接口地址
     * @param map      上传数据
     * @param file     上传文件
     * @param callBack 请求返回数据回调
     * @param <T>      数据泛型
     * @return
     */
    @SuppressWarnings({"unchecked"})
    private <T> Call requestPostByFileAsyn(final Context context, String url,
                                           File file, Map<String, Object> map, final ReqCallBack<T> callBack) {

        try {
            if (!url.startsWith(PublicIp.URL)
                    && !url.startsWith(URL_PREFIX_HTTP)) {
                url = PublicIp.URL + url;
            }
            MultipartBody.Builder requestBody = new MultipartBody.Builder()
                    .setType(MultipartBody.FORM);
            if (file != null) {
                // MediaType.parse() 里面是上传的文件类型。
                RequestBody body = RequestBody.create(
                        MediaType.parse("image/*"), file);
                String filename = file.getName();
                // 参数分别为, 请求key ,文件名称 , RequestBody
                requestBody.addFormDataPart("files", filename, body);
                requestBody.addFormDataPart("type", "1");
                requestBody.addFormDataPart(TOKEN, SignUtils.getToken(context));
                requestBody.addFormDataPart(PARAM_VERSION, getVersion(context));
                requestBody.addFormDataPart(PLATFORM, "Android");
                requestBody.addFormDataPart(DID, getUserId(context));
            }
            if (map != null) {
                // map 里面是请求中所需要的 key 和 value
                for (Map.Entry entry : map.entrySet()) {
                    requestBody.addFormDataPart(valueOf(entry.getKey()), valueOf(entry.getValue()));
                }
            }
            final Request request = new Request.Builder()
                    .post(requestBody.build()).url(url).build();
            final Call call = mOkHttpClient.newCall(request);
            call.enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                    Log.e("TAG", "==" + e.toString());
                    boolean isDestoryed = false;
                    try {
                        Activity activity = (Activity) context;
                        if (activity.isFinishing()) {
                            isDestoryed = true;
                        }
                    } catch (Exception e1) {
                        // TODO: handle exception
                    }
                    if (isDestoryed) {
                        return;
                    }
                    failedCallBack(MSG_NETWORK_ERROR, callBack);

                }

                @Override
                public void onResponse(Call call, Response response)
                        throws IOException {
                    Log.e("TAG", "==" + response.body().string());
                    boolean isDestoryed = false;
                    try {
                        Activity activity = (Activity) context;
                        if (activity.isFinishing()) {
                            isDestoryed = true;
                        }
                    } catch (Exception e) {
                        // TODO: handle exception
                    }
                    if (isDestoryed) {
                        return;
                    }
                    if (response.isSuccessful()) {
                        // 接口成功拿到数据
                        String result = response.body().string();
                        // 辨别接口返回标识码

                        /**
                         * logout代码
                         */
                        // 辨别接口返回标识码
                        String error = getErrorOfReponseString(result);
                        if (TextUtils.equals(error, "信息错误!")) {

                        }

                        if (error.equals(RESULT_SUCCESS) && callBack != null) {
                            // 成功回调
                            successCallBack((T) result, callBack);
                        } else {
                            failedCallBack(error, callBack);
                        }

                    } else {
                        failedCallBack(MSG_NETWORK_ERROR, callBack);
                    }
                }

            });
            return call;
        } catch (Exception e) {
            return null;
        }

    }

    /**
     * okHttp get异步请求
     *
     * @param url      文件地址
     * @param target   下载路径
     * @param callBack 请求返回数据回调
     * @param <T>      数据泛型
     * @return
     */
    @SuppressWarnings("unchecked")
    private <T> Call downLoad(Context context, String url, String target,
                              final ReqCallBack<T> callBack) {

        try {
            // 是否添加了文件路径
            if (!target.startsWith(context.getFilesDir().getAbsolutePath())) {
                target = getCacheFileName(target, context);
            }
            final String targetFileName = target;

            final Request request = new Request.Builder().get().url(url)
                    .build();
            final Call call = mOkHttpClient.newCall(request);
            call.enqueue(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {

                    failedCallBack(MSG_NETWORK_ERROR, callBack);

                }

                @Override
                public void onResponse(Call call, Response response)
                        throws IOException {
                    if (response.isSuccessful()) {
                        try {
                            // 接口成功拿到数据
                            // 将响应数据转化为输入流数据
                            InputStream inputStream = response.body()
                                    .byteStream();
                            FileOutputStream out = null;// 文件输出流
                            if (targetFileName.endsWith(".jpg")) {
                                // 将输入流数据转化为Bitmap位图数据
                                Bitmap bitmap = BitmapFactory
                                        .decodeStream(inputStream);
                                File file = new File(targetFileName);
                                if (!file.getParentFile().exists()) {
                                    file.getParentFile().mkdirs();// 创建文件夹
                                }
                                file.createNewFile();
                                // 创建文件输出流对象用来向文件中写入数据
                                out = new FileOutputStream(file);
                                // 将bitmap存储为jpg格式的图片
                                if (bitmap != null) {
                                    bitmap.compress(Bitmap.CompressFormat.JPEG,
                                            100, out);
                                }
                            } else {
                                File file = new File(targetFileName);
                                if (!file.getParentFile().exists()) {
                                    file.getParentFile().mkdirs();// 创建文件夹
                                }
                                file.createNewFile();
                                // 创建文件输出流对象用来向文件中写入数据
                                out = new FileOutputStream(file);
                                byte[] buf = new byte[1024 * 8];
                                int ch;
                                while ((ch = inputStream.read(buf)) != -1) {
                                    out.write(buf, 0, ch);// 将获取到的流写入文件中
                                }
                            }
                            // 刷新文件流
                            if (out != null) {
                                out.flush();
                                out.close();
                            }
                            successCallBack((T) targetFileName, callBack);
                        } catch (Exception e) {
                            // TODO: handle exception
                            failedCallBack(MSG_CDCARD_ERROR, callBack);
                        }

                    } else {
                        failedCallBack(MSG_NETWORK_ERROR, callBack);
                    }
                }

            });
            return call;
        } catch (Exception e) {
            return null;
        }

    }

    /**
     * 统一同意处理成功信息
     *
     * @param result
     * @param callBack
     * @param <T>
     */
    private <T> void successCallBack(final T result,
                                     final ReqCallBack<T> callBack) {
        okHttpHandler.post(new Runnable() {
            @Override
            public void run() {
                if (callBack != null) {
                    callBack.onReqSuccess(result);
                }
            }
        });
    }

    /**
     * 统一处理失败信息
     *
     * @param errorMsg
     * @param callBack
     * @param <T>
     */
    private <T> void failedCallBack(final String errorMsg,
                                    final ReqCallBack<T> callBack) {
        okHttpHandler.post(new Runnable() {
            @Override
            public void run() {
                if (callBack != null) {
                    callBack.onReqFailed(errorMsg);
                }
            }
        });
    }

    // 自动为在GET url中添加member_phone与version参数
    public static String getUrlWithExtras(Context context, String url) {
        if (url.indexOf(DID) == -1) {
            url = getUrlWithParam(DID, getUserId(context), url);
//            url = getUrlWithParam(DID, getUserId(context), url);
        }
        if (url.indexOf(PARAM_VERSION) == -1) {
            url = getUrlWithParam(PARAM_VERSION, getVersion(context), url);
        }
        if (url.indexOf(PLATFORM) == -1) {
            url = getUrlWithParam(PLATFORM, "Android", url);
        }
        if (url.indexOf(TOKEN) == -1) {
            url = getUrlWithParam(TOKEN, SignUtils.getToken(context), url);
        }
//		String unixtime = System.currentTimeMillis() / 1000 + "";
//		String sign = UtilsTool.getSign(unixtime).trim();
//
//		url = getUrlWithParam(UtilsTool.PARAM_UNIXTIME, unixtime, url);
//		url = getUrlWithParam(UtilsTool.PARAM_SIGN, sign, url);

        return url;
    }

    // 直接获取用户id(手机号)
    public static String getUserId(Context mContext) {
        try {
            SharedPreferences userinfo = mContext.getSharedPreferences(
                    SharePreferenceUtil.SHARE_NAME, Context.MODE_PRIVATE);
            return userinfo.getString("userid", "");
        } catch (Exception e) {
            return "";
        }
    }

    // 获取版本号
    public static String getVersion(Context context) {
        try {
            PackageInfo pi = context.getPackageManager().getPackageInfo(
                    context.getPackageName(), 0);
            // 去除版本号中的逗号
            String versionName = pi.versionName.replace(".", "");
            return versionName;
        } catch (NameNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return "";
        }
    }

    private static String getUrlWithParam(String paramName, String paramValue,
                                          String url) {
        if (url.contains(paramName + "=")) {
            return url;
        } else {
            if (url.contains("?")) {
                return String.format("%1$s&%2$s=%3$s", url, paramName,
                        paramValue);
            } else {
                return String.format("%1$s?%2$s=%3$s", url, paramName,
                        paramValue);
            }
        }
    }

    // 获取缓存文件名
    public static String getCacheFileName(String filename, Context mContext) {
        String cacheDir = mContext.getFilesDir().getAbsolutePath();
        if (filename.startsWith("/")) {
            return cacheDir + filename;
        } else {
            return cacheDir + "/" + filename;
        }
    }

    // 将String内容保存到文件中
    // 返回值: true - 成功 false - 失败
    public static Boolean saveContentToFile(String content, String filename) {
        try {
            File f = new File(filename);
            if (!f.exists()) {
                f.getParentFile().mkdirs();
                f.createNewFile();
            }
            FileOutputStream ofile = new FileOutputStream(f);
            ofile.write(content.getBytes());
            ofile.close();
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    // 返回值:
    // 是JSON且result=="1" 正确 result!="1" 错误:resultString
    // 是JSON且state=="1" 正确 state!="1" 错误:stateString
    // 是JSON且没有result或state 正确
    // 不是JSON且返回值为"1" 正确 返回值!="1" 错误:网络错误
    private static String getErrorOfReponseString(String response) {
        if (isJSON(response)) {
            try {
                JSONObject json = new JSONObject(response);
                if (json.has("result")) {
                    return json.getString("result");
                } else if (json.has("state")) {
                    return json.getString("state");

                } else if (json.has("status")) {
                    return json.getString("status");
                } else {
                    return RESULT_SUCCESS;
                }
            } catch (JSONException e) {
                return RESULT_SUCCESS;// JSONArray
            }
        } else if (response.equals(RESULT_SUCCESS)) {
            return RESULT_SUCCESS;
        } else {
            return "网络错误";
        }
    }

    // 判定字符串是否是JSONObject或JSONArray
    public static boolean isJSON(String content) {
        try {
            new JSONObject(content);
        } catch (JSONException e) {
            try {
                new JSONArray(content);
            } catch (JSONException c) {
                return false;
            }
        }
        return true;
    }

}

reqcall

package com.yaoxin.doctor.interFace;

/**
 * okhttp二次封装类回调方法
 * 
 * @author Eleven
 * 
 * @param <T>
 */
public interface ReqCallBack<T> {
	/**
	 * 响应成功
	 */
	void onReqSuccess(T result);

	/**
	 * 响应失败
	 */
	void onReqFailed(String errorMsg);
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值