Android---Xutils3.0 网络请求框架封装(包含解析)

一、Xutils 3.0简介

xUtils是目前功能比较完善的一个 Android 开源框架,最近又发布了xUtil3.0,在增加新功能的同时又提高了框架的性能,下面来看看官方( https://github.com/wyouflf/xUtils3 )对xUtils3的介绍:

  • xUtils包含了很多实用的android工具;
  • xUtils支持超大文件(超过2G)上传,更全面的http请求协议支持(11种谓词),拥有更加灵活的ORM,更多的事件注解支持且不受混淆影响;
  • xUtils 最低兼容Android 4.0 (api level 14);
  • xUtils3变化较多所以建立了新的项目不在旧版(github.com/wyouflf/xUtils)上继续维护, 相对于旧版本: 

    • HTTP实现替换HttpClient为UrlConnection, 自动解析回调泛型, 更安全的断点续传策略;
    • 支持标准的Cookie策略, 区分domain, path;
    • 事件注解去除不常用的功能, 提高性能;
    • 数据库api简化提高性能, 达到和greenDao一致的性能;
    • 图片绑定支持gif(受系统兼容性影响, 部分gif文件只能静态显示), webp; 支持圆角, 圆形, 方形等裁剪, 支持自动旋转。

二、Xutils引入和初始化(基于AS)
    1.build.gradle文件配置

    2.Application里进行初始化

x.Ext.init(this);

3、框架封装

public class NetRequestUtil {

    private volatile static NetRequestUtil instance;

    /**
     * Double Check 单例模式
     *
     * @return
     */
    public static NetRequestUtil getInstance() {
        if (instance == null) {
            synchronized (NetRequestUtil.class) {
                if (instance == null) {
                    instance = new NetRequestUtil();
                }
            }
        }
        return instance;
    }

    /**
     * /appLogin','/version','/applogout','/weekReportDel','/idcode','/islogin','/losepwd'
     * 不需要传token
     */
    public static final int REQUEST_TOKEN = 0;// 默认需要token
    public static final int REQUEST_NO_TOKEN = 1; // 在登录等几个特殊接口不需要token

    public static final int REQUEST_METHOD_GET = 0;// get请求
    public static final int REQUEST_METHOD_POST = 1; // post请求

    /**
     * 基地址
     */
    private String TestUrl = "http://a.http.cn/"; // 测试环境
  
    private String BaseUrl = TestUrl;

    /**
     * 接口地址
     */

    /  登录  退出  /
    public String LOGIN = "appLogin";  // 登录接口
    public String LOGOUT = "applogout"; // 退出
    public String IS_LOGIN = "islogin"; // 每次判断是否要重新登录,有效期内不需要每次登录
   
    /**
     * 取得完整地址
     *
     * @param apiUrl
     * @return
     */
    public String getUrl(String apiUrl) {
        return BaseUrl + apiUrl;
    }

    /**
     * 取得公共参数
     *
     * @return
     */
    public Map<String, Object> getBaseMap() {
        Map<String, Object> map = new HashMap<>();

        // 添加公参
        map.put("device_token", Tools.getDeviceId(MyApplication.getInstance())); //  设备唯一标识
        map.put("device_uuid", Tools.getDeviceId(MyApplication.getInstance()));
        map.put("appid", "android");
        map.put("version", Tools.getVersion(MyApplication.getInstance()));

        if (EmptyUtils.isNotEmpty(MyApplication.getInstance().getUser())
                && EmptyUtils.isNotEmpty(MyApplication.getInstance().getUser().getData().getUsername())) {
            map.put("username", MyApplication.getInstance().getUser().getData().getUsername());
        }

        return map;
    }

    /**
     * 异步get请求
     *
     * @param url
     * @param maps
     * @param requestCode
     * @param clazz
     * @param listener
     * @return
     */
    public Callback.Cancelable get(String url, Map<String, String> maps, final int requestCode,
                                   final Class<? extends MResponse> clazz, final NetResponseListener listener) {


        if (!NetworkUtils.isConnected()) {
            ToastU.showShortToast(R.string.no_network);
        }

        maps.put("sign", Tools.getSign(maps)); // MD5加密

        RequestParams params = new RequestParams(url);
        if (maps != null && !maps.isEmpty()) {
            for (Map.Entry<String, String> entry : maps.entrySet()) {
                params.addQueryStringParameter(entry.getKey(), entry.getValue());
            }
        }

        Callback.Cancelable cancelable = x.http().get(params, new Callback.CommonCallback<String>() {
            @Override
            public void onSuccess(String result) {
                MResponse mResponse = GsonUtil.processJS(result, clazz); //按正常响应解析
                listener.onSuccess(mResponse, requestCode, result);
            }

            @Override
            public void onError(Throwable ex, boolean isOnCallback) {
                listener.onError(ex, isOnCallback, requestCode);
            }

            @Override
            public void onCancelled(CancelledException cex) {
                listener.onCancelled(cex);
            }

            @Override
            public void onFinished() {
                listener.onFinish();
            }
        });

        return cancelable;
    }

    /**
     * 带缓存的异步get请求
     *
     * @param url
     * @param maps
     * @param requestCode
     * @param clazz
     * @param listener
     * @return
     */
    public Callback.Cancelable getCache(String url, Map<String, String> maps, final int requestCode,
                                        final Class<? extends MResponse> clazz, final NetResponseListener listener) {

        if (!NetworkUtils.isConnected()) {
            ToastU.showShortToast(R.string.no_network);
        }

        maps.put("sign", Tools.getSign(maps)); // MD5加密

        RequestParams params = new RequestParams(url);
        if (maps != null && !maps.isEmpty()) {
            for (Map.Entry<String, String> entry : maps.entrySet()) {
                params.addQueryStringParameter(entry.getKey(), entry.getValue());
            }
        }

        // 默认缓存存活时间, 单位:毫秒(如果服务器没有返回有效的max-age或Expires则参考)
        params.setCacheMaxAge(1000 * 60);//设置缓存当这个缓存事件过了的时候, 这时候就会不走这个onCache方法, 直接发起网络请求,

        Callback.Cancelable cancelable = x.http().get(params, new Callback.CacheCallback<String>() {
            @Override
            public boolean onCache(String result) {
                MResponse mResponse = GsonUtil.processJS(result, clazz);//按正常响应解析
                listener.onSuccess(mResponse, requestCode, result);
                return true;//这里返回一个true, 就是走了cache就不再发起网络请求了, 返回一个false, 就是不信任缓存数据, 再次发起网络请求
            }

            @Override
            public void onSuccess(String result) {
                if (result != null) {
                    //如果走了cache方法返回了true, 将不再发起网络请求, 这里拿到的result就是null,
                    MResponse mResponse = GsonUtil.processJS(result, clazz);//按正常响应解析
                    listener.onSuccess(mResponse, requestCode, result);
                }
            }

            @Override
            public void onError(Throwable ex, boolean isOnCallback) {
                listener.onError(ex, isOnCallback, requestCode);
            }

            @Override
            public void onCancelled(CancelledException cex) {
                listener.onCancelled(cex);
            }

            @Override
            public void onFinished() {
                listener.onFinish();
            }
        });
        return cancelable;
    }

    /**
     * 异步post请求,去除请求标志,默认为0
     *
     * @param url
     * @param maps
     * @param clazz
     * @param listener
     * @return
     */
    public Callback.Cancelable post(Context context, String url, Map<String, Object> maps,
                                    final Class<? extends MResponse> clazz, final NetResponseListener listener) {
        return post(context, url, maps, REQUEST_TOKEN, clazz, listener);
    }

    /**
     * 异步post请求
     *
     * @param context
     * @param url
     * @param maps
     * @param requestCode
     * @param clazz
     * @param listener
     * @return
     */
    public Callback.Cancelable post(final Context context, String url, Map<String, Object> maps,
                                    final int requestCode, final Class<? extends MResponse> clazz,
                                    final NetResponseListener listener) {

        if (!NetworkUtils.isConnected()) {
            ToastU.showShortToast(R.string.no_network);
        }

        if (requestCode == REQUEST_TOKEN) {
            maps.put("token", MyApplication.getInstance().getUser().getData().getToken()); // 添加token
        }

        maps.put("sign", Tools.getSign(maps)); // MD5加密

        RequestParams params = new RequestParams(url);
        params.setReadTimeout(30 * 1000); // 设置网络超时时间
        params.setConnectTimeout(30 * 1000);
        params.setMethod(HttpMethod.POST);

        if (!maps.isEmpty()) {
            for (Map.Entry<String, Object> entry : maps.entrySet()) {
                params.addParameter(entry.getKey(), entry.getValue());
            }
        }

        AppLog.i(Const.HTTP_LOG_KEY, "=======http-request-url::::::" + url);
        AppLog.i(Const.HTTP_LOG_KEY, "=======http-request-parameters::::::" + params.toString());

        //为了防止app登录成功以后im当时的登录失败,每次访问接口的时候判断一下是否需要im失败,如果失败就进行重新登录
        if (!IMUseHelper.isImLogin()) {
            IMUseHelper.initImLogin();
        }

        final Callback.Cancelable post = x.http().post(params, new Callback.CommonCallback<String>() {

            @Override
            public void onSuccess(final String result) {
                try {
                    JSONObject jsonObject = new JSONObject(result);

                    // 1. 判断为token过期则重新去登录,比如在其他设备上登录   2.人员角色变化,需要重新登录更新个人信息
                    if (jsonObject.getInt("code") == Const.LOGIN_OUT_TIME

                            || Const.ROLE_CHANGES == jsonObject.getInt("code")) {

                        if (!TextUtils.isEmpty(jsonObject.getString("message"))) {
                            ToastU.showLongToast(jsonObject.getString("message"));
                        }
                        Tools.logout(context);
                    } else {
                        final MResponse mResponse = GsonUtil.processJS(result, clazz);//按正常响应解析
                        listener.onSuccess(mResponse, requestCode, result);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }

                AppLog.i(Const.HTTP_LOG_KEY, "=======---onSuccess---======:" + result);
            }

            @Override
            public void onError(Throwable ex, boolean isOnCallback) {
                if (ex instanceof HttpException) { // 网络错误
                    HttpException httpEx = (HttpException) ex;
                    int responseCode = httpEx.getCode();
                    String responseMsg = httpEx.getMessage();
                    String errorResult = httpEx.getResult();
                    AppLog.i(Const.HTTP_LOG_KEY, "=======---onError---网络错误======:"
                            + "返回码:" + responseCode
                            + ";---错误信息:" + responseMsg
                            + ";---错误结果:" + errorResult);
                } else { // 其他错误
                    listener.onError(ex, isOnCallback, requestCode);
                    AppLog.i(Const.HTTP_LOG_KEY, "=======---onError---其他错误======:" + ex.toString());
                }

            }

            @Override
            public void onCancelled(CancelledException cex) {
                listener.onCancelled(cex);
                AppLog.i(Const.HTTP_LOG_KEY, "=======---onCancelled---======:" + cex.toString());
            }

            // 不管成功或者失败最后都会回调该接口
            @Override
            public void onFinished() {
                listener.onFinish();
                AppLog.i(Const.HTTP_LOG_KEY, "=======---onFinished---======:" + clazz);
            }
        });

        return post;
    }

    /**
     * 普通异步网络请求  get或者post
     *
     * @param context
     * @param url
     * @param maps
     * @param requestCode
     * @param requestMethod
     * @param clazz
     * @param listener
     * @return
     */
    public Callback.Cancelable httpRequest(final Context context, String url,
                                           Map<String, Object> maps,
                                           final int requestCode, int requestMethod,
                                           final Class<? extends MResponse> clazz,
                                           final NetResponseListener listener) {

        HttpMethod method = null; // 请求方式

        if (requestMethod == REQUEST_METHOD_GET) {
            method = HttpMethod.GET;
        } else {
            method = HttpMethod.POST;
        }

        // token 添加
        if (requestCode == REQUEST_TOKEN) {
            maps.put("token", MyApplication.getInstance().getUser().getData().getToken()); // 添加token
        }

        maps.put("sign", Tools.getSign(maps)); // MD5加密
        RequestParams params = new RequestParams(url);

        if (!maps.isEmpty()) {
            for (Map.Entry<String, Object> entry : maps.entrySet()) {
                params.addBodyParameter(entry.getKey(), entry.getValue().toString());
            }
        }

        Callback.Cancelable request = x.http().request(method, params, new Callback.CommonCallback<String>() {
            @Override
            public void onSuccess(String result) {
                try {
                    JSONObject jsonObject = new JSONObject(result);

                    if (jsonObject.getInt("code") == Const.LOGIN_OUT_TIME) { // 判断为token过期则重新去登录
                        ToastU.showLongToast(jsonObject.getString("message"));
                        Tools.logout(context);
                    } else {
                        final MResponse mResponse = GsonUtil.processJS(result, clazz);//按正常响应解析
                        listener.onSuccess(mResponse, requestCode, result);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }

            }

            @Override
            public void onError(Throwable ex, boolean isOnCallback) {
                if (ex instanceof HttpException) { // 网络错误
                    HttpException httpEx = (HttpException) ex;
                    int responseCode = httpEx.getCode();
                    String responseMsg = httpEx.getMessage();
                    String errorResult = httpEx.getResult();

                    AppLog.i(Const.HTTP_LOG_KEY, "=======---onError---网络错误======:"
                            + "返回码:" + responseCode
                            + ";---错误信息:" + responseMsg
                            + ";---错误结果:" + errorResult);
                } else { // 其他错误
                    listener.onError(ex, isOnCallback, requestCode);
                    AppLog.i(Const.HTTP_LOG_KEY, "=======---onError---其他错误======:" + ex.toString());
                }
            }

            @Override
            public void onCancelled(CancelledException cex) {
                listener.onCancelled(cex);
                AppLog.i(Const.HTTP_LOG_KEY, "=======---onCancelled---======:" + cex.toString());
            }

            @Override
            public void onFinished() {
                listener.onFinish();
                AppLog.i(Const.HTTP_LOG_KEY, "=======---onFinished---======:" + clazz);
            }
        });

        return request;
    }

    /**
     * 文件上传
     *
     * @param url
     * @param maps
     * @param file
     * @param requestCode
     * @param clazz
     * @param listener
     * @return
     */
    public Callback.Cancelable upLoadFile(String url, Map<String, String> maps, Map<String, File> file,
                                          final int requestCode, final Class<? extends MResponse> clazz,
                                          final NetUpLoadFileListener listener) {
        if (!NetworkUtils.isConnected()) {
            ToastU.showShortToast(R.string.no_network);
        }

        // token 添加
        if (requestCode == REQUEST_TOKEN) {
            maps.put("token", MyApplication.getInstance().getUser().getData().getToken()); // 添加token
        }

        maps.put("sign", Tools.getSign(maps)); // MD5加密
        RequestParams params = new RequestParams(url);
        params.setMethod(HttpMethod.POST);

        if (!maps.isEmpty()) {
            for (Map.Entry<String, String> entry : maps.entrySet()) {
                params.addBodyParameter(entry.getKey(), entry.getValue());
            }
        }

        if (file != null && !maps.isEmpty()) {
            for (Map.Entry<String, File> entry : file.entrySet()) {
                params.addBodyParameter(entry.getKey(), entry.getValue().getAbsoluteFile());
            }
        }

        AppLog.i(Const.HTTP_LOG_KEY, "=======http-request-url::::::" + url);
        AppLog.i(Const.HTTP_LOG_KEY, "=======http-request-parameters::::::" + params.toString());

        // 有上传文件时使用multipart表单, 否则上传原始文件流.
        params.setMultipart(true);//这个是标示上传的文件内容的,

        Callback.Cancelable upLoad = x.http().post(params, new Callback.ProgressCallback<String>() {
            @Override
            public void onSuccess(String result) {
                JSONObject jsonObject = null;

                try {
                    jsonObject = new JSONObject(result);
                    ToastU.showLongToast(jsonObject.getString("message"));
                } catch (JSONException e) {
                    e.printStackTrace();
                }

                MResponse mResponse = GsonUtil.processJS(result, clazz);//按正常响应解析
                listener.onSuccess(mResponse, requestCode, result);
                AppLog.i(Const.HTTP_LOG_KEY, "=======---onSuccess---======:" + result);
            }

            @Override
            public void onError(Throwable ex, boolean isOnCallback) {
                listener.onError(ex, isOnCallback, requestCode);
                AppLog.i(Const.HTTP_LOG_KEY, "=======---onError---======:" + ex.toString());
            }

            @Override
            public void onCancelled(CancelledException cex) {
                listener.onCancelled(cex);
                AppLog.i(Const.HTTP_LOG_KEY, "=======---onCancelled---======:" + cex.toString());
            }

            @Override
            public void onFinished() {
                listener.onFinish();
                AppLog.i(Const.HTTP_LOG_KEY, "=======---onFinished---======:");
            }

            @Override
            public void onWaiting() {
                listener.onWaiting();
                AppLog.i(Const.HTTP_LOG_KEY, "=======---onWaiting---======:");
            }

            @Override
            public void onStarted() {
                listener.onStarted();
                AppLog.i(Const.HTTP_LOG_KEY, "=======---onStarted---======:");
            }

            @Override
            public void onLoading(long total, long current, boolean isDownloading) {
                listener.onLoading(current, isDownloading, requestCode);
                AppLog.i(Const.HTTP_LOG_KEY, "=======---onLoading---======:"
                        + "total:" + total + "---current:"
                        + current + "---isDownloading:"
                        + isDownloading);
            }
        });

        return upLoad;
    }

    /**
     * 文件下载
     *
     * @param url
     * @param filepath
     * @param requestCode
     * @param listener
     */
    public void downLoadFile(String url, String filepath, final int requestCode, final NetDownLoadFileListener listener) {

        if (!NetworkUtils.isConnected()) {
            ToastU.showShortToast(R.string.no_network);
        }

        RequestParams params = new RequestParams(url);
        params.setAutoRename(true);// 断点续传, 也就是说支持中断之后再继续下载,
        params.setSaveFilePath(filepath);//设置文件保存的路径

        x.http().post(params, new Callback.ProgressCallback<File>() {
            @Override
            public void onSuccess(final File result) {
                listener.onSuccess(result, requestCode);
            }

            @Override
            public void onError(Throwable ex, boolean isOnCallback) {
                listener.onError(ex, isOnCallback, requestCode);
            }

            @Override
            public void onCancelled(CancelledException cex) {
                listener.onCancelled(cex);
            }

            @Override
            public void onFinished() {
                listener.onFinish();
            }

            @Override
            public void onWaiting() {
                listener.onWaiting();
            }

            @Override
            public void onStarted() {
                listener.onStarted();
            }

            @Override
            public void onLoading(final long total, final long current, final boolean isDownloading) {
                listener.onLoading(current, isDownloading, requestCode);
            }
        });

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值