Giter VIP home page Giter VIP logo

xuexiangjys / xhttp2 Goto Github PK

View Code? Open in Web Editor NEW
398.0 16.0 83.0 13.94 MB

💪A powerful network request library, encapsulated using the RxJava2 + Retrofit2 + OKHttp combination.(一个功能强悍的网络请求库,使用RxJava2 + Retrofit2 + OKHttp组合进行封装)

Home Page: https://github.com/xuexiangjys/XHttp2/wiki

License: Apache License 2.0

Java 100.00%
xhttp gradle rxjava cookie rxjava2-retrofit2-okhttp x-library

xhttp2's Issues

如何显示服务器端返回的httpstate的自定义消息,

服务器响应结果:HttpState:401,response body返回下面的内容

{
"code": 401,
"data": "用户不存在",
"message": "Unauthorized"
}

请问如何在UI上面显示这个json里面data属性的消息?
XHttpSDK.setSuccessCode(200); 设置过200了。
拦截器

public class CustomExpiredInterceptor extends BaseExpiredInterceptor {
@OverRide
protected ExpiredInfo isResponseExpired(Response oldResponse, String bodyString) {
int code = JSONUtils.getInt(bodyString.toLowerCase(), "code", 0);
ExpiredInfo expiredInfo = new ExpiredInfo(code);
expiredInfo.setExpiredType(code)
.setCode(code)
.setBodyString(bodyString);
return expiredInfo;
}
@SuppressLint("CheckResult")
@OverRide
protected Response responseExpired(Response oldResponse, Chain chain, ExpiredInfo expiredInfo) {
return HttpUtils.getErrorResponse(oldResponse, expiredInfo.getCode(), expiredInfo.getBodyString());
}
}

登录操作

XHttpSDK.postToMain(login).execute(new SimpleCallBack() {
@OverRide
public void onSuccess(String token) throws Throwable {
if (!TextUtils.isEmpty(token)) {
LoginFragment.super.popToBack();
ActivityUtils.startActivity(MainActivity.class);
} else {
ToasterUtils.error("token没有!");
}
}
@OverRide
public void onError(ApiException e) {
ToasterUtils.error(e.getMessage(), 3000);
XLog.get().e(e, e.getMessage());
}
});

请更新下三方库支持版本

implementation 'com.squareup.okhttp3:okhttp:3.10.0'
implementation 'io.reactivex.rxjava2:rxjava:2.2.0'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
使用最新的三方库,暴露很多问题哟。

PUT请求无法被拦截添加请求头的问题

问题描述(必填)
on 29 Jan 动态拦截器支持请求头的更新

BaseDynamicInterceptor 里面只做了对 GET 和 POST 的拦截处理,既然 XHttp2 支持 PUT 和 DELETE ,我认为有必要也做一下拦截,一视同仁。

使用的XHttp2版本(必填)
2.0.4(最新版本)

如何重现(必填)
重现的步骤:

  1. CustomDynamicInterceptor 添加Token,打个断点
  2. XHttp.put().accessToken(true)
  3. 请求时,CustomDynamicInterceptor断点无法进入

期望的效果
期望 BaseDynamicInterceptor 中添加对 PUT 和 DELETE 的拦截支持。

截图
image

使用自定义请求响应,获取不到result

问题描述

由于请求返回code为字符串且正常码为“00000000”,所以自定义了请求响应
只对errorCode做了Integer.parseInt(errorCode),但在运行时报空指针错误,打断点发现除了errorCode为0,errorInfo和result均为null

使用的XHttp2版本

1.0.2

如何重现

自定义请求响应,将参考的

    public CustomApiResult<T> setErrorCode(int errorCode) {
        this.errorCode = errorCode;
        return this;
    }

修改为

    public CustomApiResult<T> setErrorCode(String errorCode) {
        this.errorCode = Integer.parseInt(errorCode);
        return this;
    }

请求方式

XHttp.post("/test/res")
                .baseUrl(App.URL_BASE)
                .execute(new CallBackProxy<CustomApiResult<Response>, Response>(new SimpleCallBack<Response>() {
                    @Override
                    public void onSuccess(Response response) throws Throwable {
                        callBack.onSuccess(response);
                    }

                    @Override
                    public void onError(ApiException e) {
                        callBack.onError(e);
                    }
                }){});

期望的效果

正常获得返回值

截图

断点截图

日志

2019-12-03 15:30:03.005 21871-25669/com.SpaceElves.box I/XHttp: -------------------------------response-------------------------------
2019-12-03 15:30:03.006 21871-25669/com.SpaceElves.box I/XHttp: <-- 200 OK https://prod.api.spaceevels.com/test/res (346ms)
2019-12-03 15:30:03.006 21871-25669/com.SpaceElves.box I/XHttp:  
2019-12-03 15:30:03.006 21871-25669/com.SpaceElves.box I/XHttp: 	Server: nginx
2019-12-03 15:30:03.006 21871-25669/com.SpaceElves.box I/XHttp: 	Date: Tue, 03 Dec 2019 07:30:03 GMT
2019-12-03 15:30:03.006 21871-25669/com.SpaceElves.box I/XHttp: 	Content-Type: application/json; charset=UTF-8
2019-12-03 15:30:03.006 21871-25669/com.SpaceElves.box I/XHttp: 	Transfer-Encoding: chunked
2019-12-03 15:30:03.006 21871-25669/com.SpaceElves.box I/XHttp: 	Connection: keep-alive
2019-12-03 15:30:03.006 21871-25669/com.SpaceElves.box I/XHttp: 	X-Powered-By: PHP/7.3.0
2019-12-03 15:30:03.006 21871-25669/com.SpaceElves.box I/XHttp: 	Cache-Control: no-cache
2019-12-03 15:30:03.007 21871-25669/com.SpaceElves.box I/XHttp:  
2019-12-03 15:30:03.008 21871-25669/com.SpaceElves.box I/XHttp: 	body:{"code":"00000000","msg":"服务调用成功!","data":{"token":"eaa824d3b50a53d38200084373e5f626"}}
2019-12-03 15:30:03.008 21871-25669/com.SpaceElves.box I/XHttp: <-- END HTTP
2019-12-03 15:30:03.016 21871-25669/com.SpaceElves.box D/CustomApiResult: isSuccess(): errorCode = 0
2019-12-03 15:30:03.016 21871-25669/com.SpaceElves.box D/CustomApiResult: isSuccess(): return = true
2019-12-03 15:30:03.017 21871-21871/com.SpaceElves.box E/XHttp: --> Subscriber is onError
2019-12-03 15:30:03.017 21871-21871/com.SpaceElves.box E/XHttp: --> e instanceof ApiException, message:空指针错误

设备信息

  • 设备名: 小米6
  • Android版本: Android 9
  • 设备型号 MI 6
  • 系统版本 MIUI 11 9.11.28

Xhttp 请求生命周期绑定

你好,我阅读了文档,网络请求生命周期和Activity/Fragment生命周期绑定,请问在XHTTP请求中如何使用RxJava的compose的操作符进行绑定?Xhttp请求中无法调用compose函数

返回code为String类型,需要怎么操作

问题描述(必填)
http接口返回的是String类型的code,需要修改框架中的哪写部分?

使用的XHttp2版本(必填)
2.0.2

期望的效果
自定义ApiResult,并且code为String类型

addPostParamsSign

image
private Request addPostParamsSign(Request request) throws UnsupportedEncodingException {
if (request.body() instanceof FormBody) {
FormBody.Builder bodyBuilder = new FormBody.Builder();
FormBody formBody = (FormBody) request.body();

        //原有的参数
        TreeMap<String, Object> oldParams = new TreeMap<>();
        for (int i = 0; i < formBody.size(); i++) {
            oldParams.put(formBody.encodedName(i), formBody.encodedValue(i));
        }

        //拼装新的参数
        TreeMap<String, Object> newParams = updateDynamicParams(oldParams);
        Utils.checkNotNull(newParams, "newParams == null");
        for (Map.Entry<String, Object> entry : newParams.entrySet()) {
            String value = URLDecoder.decode(String.valueOf(entry.getValue()), HttpUtils.UTF8.name());
            bodyBuilder.addEncoded(entry.getKey(), value);
        }
        String url = HttpUtils.createUrlFromParams(HttpUtils.parseUrl(mHttpUrl.url().toString()), newParams);
        HttpLog.i(url);
        formBody = bodyBuilder.build();
        request = createNewRequest(request.newBuilder().post(formBody));
    } else if (request.body() instanceof MultipartBody) {
        MultipartBody multipartBody = (MultipartBody) request.body();
        MultipartBody.Builder bodyBuilder = new MultipartBody.Builder().setType(MultipartBody.FORM);
        List<MultipartBody.Part> oldParts = multipartBody.parts();

        //拼装新的参数
        List<MultipartBody.Part> newParts = new ArrayList<>(oldParts);
        TreeMap<String, Object> oldParams = new TreeMap<>();
        TreeMap<String, Object> newParams = updateDynamicParams(oldParams);
        for (Map.Entry<String, Object> paramEntry : newParams.entrySet()) {
            MultipartBody.Part part = MultipartBody.Part.createFormData(paramEntry.getKey(), String.valueOf(paramEntry.getValue()));
            newParts.add(part);
        }
        for (MultipartBody.Part part : newParts) {
            bodyBuilder.addPart(part);
        }
        multipartBody = bodyBuilder.build();
        request = createNewRequest(request.newBuilder().post(multipartBody));
    } else if (request.body() instanceof RequestBody) {
        TreeMap<String, Object> params = updateDynamicParams(new TreeMap<String, Object>());
        String url = HttpUtils.createUrlFromParams(HttpUtils.parseUrl(mHttpUrl.url().toString()), params);
        request = createNewRequest(request.newBuilder().url(url));
    }
    return request;
}

URLDecoder.decode 需要修改为URLEncoder.encode

xhttp2使用时提示类型转换错误

提Bug前需要做的事情

1.如果是集成问题的话,请保证仔细按照如何引用的步骤,一步一步来,不要跳步骤!
2.详细阅读过使用手册,并且确保是框架的问题。

如果以上都不能解决你的问题,那么请按照以下说明仔细填写信息,这里需要说明的是:不符合填写要求的issue一律不予理会,希望这样能节约大家的时间!


问题描述(必填)
xhttp2使用时提示类型转换错误

使用的XHttp2版本(必填)
最新版本

如何重现(必填)
重现的步骤:
xhttp2使用时提示类型转换错误,第一次使用这个框架,不清楚怎么回事,也没有找到相关的答案。

期望的效果
对你期望的效果进行清晰而简明的描述。

截图
如果方便的话,贴一下程序截图和代码片段以帮助解释您的问题。

设备信息
请填写一下你运行设备的信息,信息越全越有助于我理解问题

  • 设备名: [e.g. 华为P20]
  • Android版本: [e.g. Android 7.0]
  • 设备型号 [e.g. ]
  • 系统版本(手机厂商定制rom)

附加信息
在此处添加任何有关该问题的任何其他说明。

org.json.JSONException: No value for Code

你好 我这样写
.onMainThread(true)
.execute(new SimpleCallBack() {
@OverRide
public void onSuccess(User response) {
Log.e("test","返回的response--->"+response.toString());
}
@OverRide
public void onError(ApiException e) {
Log.e("test","返回的error--->"+e.getDetailMessage());
}

            });

然后发生了下面的错误 请问数据格式有要求吗? 不能直接获取一个jsonObject吗?

org.json.JSONException: No value for Code
2018-08-14 14:51:11.805 24706-24851/org.telegram.biyouchat.beta W/System.err: at org.json.JSONObject.get(JSONObject.java:389)
2018-08-14 14:51:11.805 24706-24851/org.telegram.biyouchat.beta W/System.err: at org.json.JSONObject.getInt(JSONObject.java:478)
at com.xuexiang.xhttp2.transform.func.ApiResultFunc.checkApiResult(ApiResultFunc.java:174)

网络请求成功,但总是进入onError()方法

问题描述(必填)

在app开发过程中请求后端API没有问题,打包成 release apk 并安装到手机后请求报错,总是进入onError()方法,但是请求是成功的。(备注:如果打成 debug 的 apk 是没有问题的,打成 release apk 就有这个问题,不知道为什么,还希望作者大大帮忙看看)。

使用的XHttp2版本(2.0.4)

如何重现(必填)

网络请求报错问题。

期望的效果

请求成功进入onSuccess()方法。

截图

  1. 请求方法代码截图:

image

  1. 请求响应以及报错截图:

image

可以看到请求报错了,message为null

3.自定义api代码截图:

image

设备信息

  • 设备名: [小米手机]
  • Android版本: [Android 10.0]

空值处理方法分享

分享:由于 rxJava2 不支持空值传递,所以 ApiResult 中 data 为空时会抛异常,所以小弟做了以下修改

image

位于:com.xuexiang.xhttp2.transform.func.ApiResultFunc

Subscriber is onError

ttp]: -------------------------------response-------------------------------
I/[XHttp]: <-- 200 http://192.168.1.101:19081/shoes/query/89851 (271ms)

I/[XHttp]: Content-Type: application/json;charset=UTF-8
I/[XHttp]: Transfer-Encoding: chunked
Date: Mon, 04 Feb 2019 05:04:16 GMT
I/[XHttp]: Cache-Control: no-cache
I/[XHttp]:
I/[XHttp]: body:{"shoes":{"id":8,"name":"Belle/百丽冬季专柜同款黑色牛皮/人造革男休闲鞋5KF01DM7","price":"439","buyer":2122,"type":1,"cover":"http://res.warunion.com/shoes/89851/100573221.jpg","identifier":89851,"size":"40,41,42,43,44","color":"黑色,白色,蓝色","shopid":0,"isself":0,"status":0,"slaveprice":111.0,"quantity":345,"currenttime":"2019-02-03"},"images":[{"id":1,"identifier":222,"shoesidentifier":89851,"imageaddr":"http://res.warunion.com/shoes/89851/100573221_00_b.jpg","imagestatus":1,"shoesorder":1},{"id":2,"identifier":221,"shoesidentifier":89851,"imageaddr":"http://res.warunion.com/shoes/89851/100573221_01_b.jpg","imagestatus":1,"shoesorder":2},{"id":3,"identifier":223,"shoesidentifier":89851,"imageaddr":"http://res.warunion.com/shoes/89851/100573221_02_b.jpg\r\n","imagestatus":1,"shoesorder":3},{"id":4,"identifier":224,"shoesidentifier":89851,"imageaddr":"http://res.warunion.com/shoes/89851/100573221_03_b.jpg\r\n","imagestatus":1,"shoesorder":4},{"id":5,"identifier":225,"shoesidentifier":89851,"imageaddr":"http://res.warunion.com/shoes/89851/100573221_04_b.jpg\r\n","imagestatus":1,"shoesorder":5},{"id":6,"identifier":226,"shoesidentifier":89851,"imageaddr":"http://res.warunion.com/shoes/89851/100573221_10_b.jpg\r\n","imagestatus":1,"shoesorder":6},{"id":7,"identifier":227,"shoesidentifier":89851,"imageaddr":"http://res.warunion.com/shoes/89851/100573221_11_b.jpg\r\n","imagestatus":1,"shoesorder":7},{"id":8,"identifier":228,"shoesidentifier":89851,"imageaddr":"http://res.warunion.com/shoes/89851/100573221_12_b.jpg","imagestatus":1,"shoesorder":8},{"id":9,"identifier":229,"shoesidentifier":89851,"imageaddr":"http://res.warunion.com/shoes/89851/100573221_40_b.jpg","imagestatus":1,"shoesorder":9},{"id":10,"identifier":230,"shoesidentifier":89851,"imageaddr":"http://res.warunion.com/shoes/89851/100573221_41_b.jpg\r\n","imagestatus":1,"shoesorder":10},{"id":11,"identifier":231,"shoesidentifier":89851,"imageaddr":"http://res.warunion.com/shoes/89851/100573221_42_b.jpg\r\n","imagestatus":1,"shoesorder":11},{"id":12,"identifier":232,"shoesidentifier":89851,"imageaddr":"http://res.warunion.com/shoes/89851/100573221_51_b.jpg\r\n","imagestatus":1,"shoesorder":12},{"id":13,"identifier":233,"shoesidentifier":89851,"imageaddr":"http://res.warunion.com/shoes/89851/100573221_52_b.jpg\r\n","imagestatus":1,"shoesorder":13},{"id":14,"identifier":234,"shoesidentifier":89851,"imageaddr":"http://res.warunion.com/shoes/89851/100573221_52_b.jpg\r\n","imagestatus":1,"shoesorder":14}]}
I/[XHttp]: <-- END HTTP
E/[XHttp]: --> Subscriber is onError
--> e instanceof ApiException, message:空指针错误
E/[Logger]: com.xuexiang.xhttp2.exception.ApiException: 空指针错误
at com.xuexiang.xhttp2.exception.ApiExceptionHandler.handleException(ApiExceptionHandler.java:51)
at com.xuexiang.xhttp2.transform.func.HttpResponseThrowableFunc.apply(HttpResponseThrowableFunc.java:34)
at com.xuexiang.xhttp2.transform.func.HttpResponseThrowableFunc.apply(HttpResponseThrowableFunc.java:31)
at io.reactivex.internal.operators.observable.ObservableOnErrorNext$OnErrorNextObserver.onError(ObservableOnErrorNext.java:91)
at io.reactivex.internal.observers.BasicFuseableObserver.onError(BasicFuseableObserver.java:100)
at io.reactivex.internal.observers.BasicFuseableObserver.fail(BasicFuseableObserver.java:110)
at io.reactivex.internal.operators.observable.ObservableMap$MapObserver.onNext(ObservableMap.java:61)
at io.reactivex.internal.operators.observable.ObservableMap$MapObserver.onNext(ObservableMap.java:64)
at retrofit2.adapter.rxjava2.BodyObservable$BodyObserver.onNext(BodyObservable.java:51)
at retrofit2.adapter.rxjava2.BodyObservable$BodyObserver.onNext(BodyObservable.java:37)
at retrofit2.adapter.rxjava2.CallExecuteObservable.subscribeActual(CallExecuteObservable.java:44)
at io.reactivex.Observable.subscribe(Observable.java:12005)
at retrofit2.adapter.rxjava2.BodyObservable.subscribeActual(BodyObservable.java:34)
at io.reactivex.Observable.subscribe(Observable.java:12005)
at io.reactivex.internal.operators.observable.ObservableMap.subscribeActual(ObservableMap.java:33)
at io.reactivex.Observable.subscribe(Observable.java:12005)
at io.reactivex.internal.operators.observable.ObservableMap.subscribeActual(ObservableMap.java:33)
at io.reactivex.Observable.subscribe(Observable.java:12005)
at io.reactivex.internal.operators.observable.ObservableOnErrorNext.subscribeActual(ObservableOnErrorNext.java:38)
at io.reactivex.Observable.subscribe(Observable.java:12005)
at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeTask.run(ObservableSubscribeOn.java:96)
at io.reactivex.Scheduler$DisposeTask.run(Scheduler.java:571)
at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:66)
at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:57)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:301)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:764)
D/EGL_emulation: eglMakeCurrent: 0xdd305480: ver 2 0 (tinfo 0xdd303790)
D/EGL_emulation: eglMakeCurrent: 0xdd305480: ver 2 0 (tinfo 0xdd303790)

关于ApiResultFunc.parseCustomApiResult()方法有可能造成空指针的问题

问题描述(必填)
有些后端业务,完成之后,data会返回为null,会造成空指针错误。

比如,简单的注册,成功后返回:
{
code:0,
msg:"success",
data:null
}
我在使用的时候,这样会造成空指针错误,Debug半天没找到在哪修改。
后来干脆就在 ApiResultFunc.parseCustomApiResult() 这个方法里,解析完 json 之后,判断一下 data 是否为null,是null 的话,就用 new Object() 代替一下。

 ApiResult result = mGson.fromJson(json, mType);

if (result.getData() == null) {

    result.setData(new Object());

}

这样做是否正确?是我代码逻辑错误,还是框架Bug?

使用的XHttp2版本(必填)
2.0.0

如何重现(必填)
重现的步骤:

  1. 后端 data 返回为 null
  2. 前端使用 new SimpleCallBack<Object>(){} 回调

期望的效果
期望回答一下,这样做是否正确?是我代码逻辑错误,还是框架Bug?

截图
image

如何开启同步请求的?

兄弟,怎么开启同步请求的?我这么写 syncRequest(true).onMainThread(false) 还是会报错:W/System.err: android.os.NetworkOnMainThreadException

大佬,能否兼容一下非正常返回的ApiResult中,服务端返回 data 为空字符串的这种情况?或者解决方案 谢谢

提Bug前需要做的事情

1.如果是集成问题的话,请保证仔细按照如何引用的步骤,一步一步来,不要跳步骤!
2.详细阅读过使用手册,并且确保是框架的问题。

如果以上都不能解决你的问题,那么请按照以下说明仔细填写信息,这里需要说明的是:不符合填写要求的issue一律不予理会,希望这样能节约大家的时间!


问题描述(必填)

大佬,能否兼容一下非正常返回的ApiResult中,服务端返回 data 为空字符串的这种情况?
正常的返回都没有问题,框架很完美,但是异常数据 或者空的数据 就会有解析错误的问题!
当然。这不是框架的问题,框架很完美,要是能更好的兼容非正常数据 那就太完美了!

使用的XHttp2版本(必填)

最新版本

如何重现(必填)
重现的步骤:

  1. Go to '...'
  2. Click on '....'
  3. Scroll down to '....'
  4. See error

期望的效果
对你期望的效果进行清晰而简明的描述。

截图
如果方便的话,贴一下程序截图和代码片段以帮助解释您的问题。

设备信息
请填写一下你运行设备的信息,信息越全越有助于我理解问题

  • 设备名: [e.g. 华为P20]
  • Android版本: [e.g. Android 7.0]
  • 设备型号 [e.g. ]
  • 系统版本(手机厂商定制rom)

附加信息
在此处添加任何有关该问题的任何其他说明。

如何经行多个业务请求的输入

我下面这些用法很麻烦,数据传输有时候也有问题
我想了解下xhttp2 在动态出入baseURL 怎么弄
我看你的代码是在application 的 oncreate 中注入
XHttpSDK.setBaseUrl(SettingSPUtils.getInstance().getApiURL()); //设置网络请求的基础地址

这样就有点被动,如果
我有多个ApiURL 那你这个就不能使用了
如下

使用
RetrofitFactory.getInstance(MyApi.APP_SHOP_DOMAIN)
.getShoesService().getShoesPage(0,7)
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.newThread())
.subscribe(new Consumer<List>() {
@OverRide
public void accept(List shoesList) throws Exception {
AdShoesDataAdapter adShoesDataAdapter = new AdShoesDataAdapter(getContext(), shoesList);
adShoesView.setAdapter(adShoesDataAdapter);
adShoesDataAdapter.setmItemClickListener(new AdShoesDataAdapter.MyItemClickListener() {
@OverRide
public void onItemClick(View view, int position) {
Intent intent = new Intent(getContext(), GroupBuyingActivity.class);
intent.putExtra("identifier", String.valueOf(shoesList.get(position).getIdentifier()));
startActivity(intent);
}
});
}
});

public interface MyApi {

String APP_STUDY_DOMAIN = "http://192.168.1.101:10082";
String APP_SHOP_DOMAIN = "http://192.168.1.101:10081";

}

public class RetrofitFactory {

private  ShoesService mShoesService;
private static RetrofitFactory instance;
private static final int TIMEOUT_READ = 15;
private static final int TIMEOUT_CONNECTION = 15;

public static RetrofitFactory getInstance(String baseURL) {
    if (instance == null) {
        synchronized (RetrofitManager.class) {
            if (instance == null) {
                instance = new RetrofitFactory(baseURL);
            }
        }
    }
    return instance;
}

public RetrofitFactory(String baseURL) {
    get(baseURL);
}

private <T> T create(String baseURL, Class<T> service){
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(baseURL)
            .addConverterFactory(GsonConverterFactory.create())
            .client(MyHttpApplication.getApplication().createOkHttpClient())
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .build();
    return retrofit.create(service);
}


private void get(String baseURL){

    HttpLoggingInterceptor logInterceptor = new HttpLoggingInterceptor("App Loging : ");
    HttpLoggingInterceptor.Level level = BuildConfig.DEBUG ?
            HttpLoggingInterceptor.Level.HEADERS :
            HttpLoggingInterceptor.Level.NONE;
    logInterceptor.setLevel(level);

    Gson gson = new GsonBuilder()
            .setDateFormat("yyyy-MM-dd'T'HH:mm:ss")
            .create();

    OkHttpClient mOkHttpClient = new OkHttpClient.Builder()
            .retryOnConnectionFailure(true)
            .addInterceptor(new LoggingInterceptor())
            .readTimeout(TIMEOUT_READ, TimeUnit.SECONDS)
            .connectTimeout(TIMEOUT_CONNECTION, TimeUnit.SECONDS)
            .build();
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(baseURL)
            .addConverterFactory(GsonConverterFactory.create(gson))
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .client(mOkHttpClient)
            .build();
    this.mShoesService = retrofit.create(ShoesService.class);
}

public ShoesService getShoesService() {
    return mShoesService;
}

class LoggingInterceptor implements Interceptor {
    @Override
    public Response intercept(Interceptor.Chain chain) throws IOException {
        //这个chain里面包含了request和response,所以你要什么都可以从这里拿
        Request request = chain.request();
        long t1 = System.nanoTime();//请求发起的时间
        LogUtils.sf(String.format("发送请求 %s on %s%n%s",
                request.url(), chain.connection(), request.headers()));
        Response response = chain.proceed(request);
        long t2 = System.nanoTime();//收到响应的时间
        //这里不能直接使用response.body().string()的方式输出日志
        //因为response.body().string()之后,response中的流会被关闭,程序会报错,我们需要创建出一
        //个新的response给应用层处理
        ResponseBody responseBody = response.peekBody(1024 * 1024);
        LogUtils.sf(String.format("接收响应: [%s] %n返回json:【%s】 %.1fms%n%s",
                response.request().url(),
                responseBody.string(),
                (t2 - t1) / 1e6d,
                response.headers()));
        return response;
    }
}

}

使用Xhttp2 出现 BEGIN_OBJECT but was BEGIN_ARRAY 错误

W/System.err: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 2 column 2 path $

网上搜了一下,发现很多使用 使用RxJava2 + Retrofit2 的都容易出现这样的问题,建议针对这样的问题进行处理,现在找不到处理的地方

请求后台总是返回onError,不会进onSuccess

请求后台部分的代码

            HttpHeaders httpHeaders = new HttpHeaders();
            httpHeaders.put("Accept", "application/json, text/plain, */*");
            String token = TokenUtils.getToken();
            String author = "Bearer " + token;
            httpHeaders.put("Authorization", author);
            String reqJson = new Gson().toJson(bizRideOrder1);
            HttpParams params = new HttpParams();
            List<BizRideOrder> result = new ArrayList<>();
            XHttp.post("/system/order")
                    .upJson(reqJson)
                    .headers(httpHeaders)
                    .onMainThread(true)
                    .execute(new SimpleCallBack<BizRideOrder>() {
                        @Override
                        public void onSuccess(BizRideOrder response) throws Throwable {
                            bizRideOrder = response;
                            flags = true;
                        }
                        @Override
                        public void onError(ApiException e) {
                            ToastUtils.toast(e.toString());
                        }
                    });

请求返回的日志截图:
image

全局配置:
image

不支持直接返回jsonObject格式

提Bug前需要做的事情

1.如果是集成问题的话,请保证仔细按照如何引用的步骤,一步一步来,不要跳步骤!
2.详细阅读过使用手册,并且确保是框架的问题。

如果以上都不能解决你的问题,那么请按照以下说明仔细填写信息,这里需要说明的是:不符合填写要求的issue一律不予理会,希望这样能节约大家的时间!


问题描述(必填)
对问题进行清晰而简明的描述,把握问题的关键点。

使用的XHttp2版本(必填)

如何重现(必填)
重现的步骤:

  1. Go to '...'
  2. Click on '....'
  3. Scroll down to '....'
  4. See error

期望的效果
对你期望的效果进行清晰而简明的描述。

截图
如果方便的话,贴一下程序截图和代码片段以帮助解释您的问题。

设备信息
请填写一下你运行设备的信息,信息越全越有助于我理解问题

  • 设备名: [e.g. 华为P20]
  • Android版本: [e.g. Android 7.0]
  • 设备型号 [e.g. ]
  • 系统版本(手机厂商定制rom)

附加信息
在此处添加任何有关该问题的任何其他说明。

apk打包后的软件,接受后台返回数据为空

问题描述(必填)
在进行debug的时候程序无异常,但打包为apk,进行安装后,接受返回数据为空

使用的XHttp2版本(必填)
2.0.4

如何重现(必填)
重现的步骤:
XHttp.post("/user/tet")
.params("uphone",etPhoneNumber.getText().toString())
.params("upsd",etVerifyCode.getText().toString())
// .upJson(JsonUtil.toJson(user))
.syncRequest(false)
.execute(new SimpleCallBack() {
@OverRide
public void onSuccess(User response) throws Throwable {
Util.setUser(response);
ActivityUtils.startActivity(MainActivity.class);
}
@OverRide
public void onError(ApiException e) {
XToastUtils.toast("账号或密码错误");
System.out.println("Error");
}
});

response 为空

期望的效果
对你期望的效果进行清晰而简明的描述。

截图
如果方便的话,贴一下程序截图和代码片段以帮助解释您的问题。

设备信息
请填写一下你运行设备的信息,信息越全越有助于我理解问题

  • 设备名: [e.g. 华为P20]
  • Android版本: [e.g. Android 7.0]
  • 设备型号 [e.g. ]
  • 系统版本(手机厂商定制rom)

附加信息
在此处添加任何有关该问题的任何其他说明。

如果服务器端返回的Data字段为null会报“空指针错误”

问题描述(必填)
返回格式完全参照:https://github.com/xuexiangjys/XHttp2/wiki/Response%E5%AE%9E%E4%BD%93%E8%A7%84%E8%8C%83 中的标准格式,但是如果服务器端返回的Data字段为null会报“空指针错误”。

使用的XHttp2版本(必填)
2.0.0(使用当前最新的 https://github.com/xuexiangjys/TemplateAppProject 模板)

如何重现(必填)
重现的步骤:
使用XHttpProxy进行请求,如果服务器端接口返回数组中Data为null则报空指针错误。非null不会有这个错误。

期望的效果
Data为null时将对象解析为null,而不是抛出错误。

这个是不是不支持嵌套泛型啊?

json如下

{
	"code": "0",
	"msg": "成功!",
	"data": {
		"list": [
			{ "id": "112", "name": "巡检0002#" },
			{ "id": "113", "name": "巡检0003#" },
		],
		"total": 7,
		"size": 20,
		"current": 1
	}
}

我定义的 类如下

public class PageRes<T> {
        private Integer total;
        private Integer size;
        private Integer current;
}

这个 T可能是 设备类 ,或者 是 其他 的 类
然后 我用请求

        XHttp.post("/netservice/net/inspection/page")
                .upJson(JsonUtil.toJson(new BaseQueryParams(1, 20)))
                .execute(new TipCallBack<PageRes<Device>>() {
                    @Override
                    public void onSuccess(PageRes<Device> response) {
                    }

这样解析会报 类型转换错误
但是我 如果 把 泛型去掉 ,他就能解析了

        XHttp.post("/netservice/net/inspection/page")
                .upJson(JsonUtil.toJson(new BaseQueryParams(1, 20)))
                .execute(new TipCallBack<PageRes>() {
                    @Override
                    public void onSuccess(PageRes response) {
// 泛型去掉可以解析,但是我要 自己 解析 response 里面 的list 转成 实体列表 

                    }

作者能不能加上 嵌套 泛型支持呢

设置非严格模式不起作用

问题描述(必填)
设置非严格模式后,依然会空指针

使用的XHttp2版本(必填)
2.0.4

如何重现(必填)
1.XHttp.getInstance().setStrictMode(false);
2.发送一个简单业务请求

期望的效果
data:null时不报空指针

截图
image

使用疑問

问题描述(必填)
再使用过程中, 自定义请求响应的API结构 CustomApiResult ,问我如果想在 执行结果成功 里面,如何能拿到 第一层级里面的 result 字段, 因为 SimpleCallBack 中 传递的类型一般都是 T data , 的类型。 onSuccess 只能拿到 轉換後的 data 數據。 如何拿到 第一層級的 其它字段?

image

文件上传在真机上总是报网络请求超时,而模拟器上基本不会

问题描述(必填)

写了个图片上传功能,用到了文件上传,但是在真机上总是报网络请求超时错误,即使设置了超时时间为60s。而模拟器上基本不会有这个问题。希望作者大大帮忙看看👀,感谢

使用的XHttp2版本(2.04)

期望的效果

不管是真机还是模拟器都能成功上传图片。

截图

图片上传代码:

image

真机报错:

image

模拟器成功上传图片,但是也报这个错:

image

设备信息

  • 设备名: [小米手机]
  • Android版本: [Android 10.0]

根据文件路径获取不到文件

因为项目需要用SDK30,上传文件时,出现:
I/[XHttp]: <-- HTTP FAILED: /storage/emulated/0/Android/data/com.xuexiang.templateproject/cache/XQRCode_1652508557266.png (No such file or directory)
E/[XHttp]: --> Subscriber is onError
E/[XHttp]: --> e instanceof ApiException, message:java.io.FileNotFoundException: /storage/emulated/0/Android/data/com.xuexiang.templateproject/cache/XQRCode_1652508557266.png (No such file or directory)
E/[XHttp]: com.xuexiang.xhttp2.exception.ApiException: java.io.FileNotFoundException: /storage/emulated/0/Android/data/com.xuexiang.templateproject/cache/XQRCode_1652508557266.png (No such file or directory)
at com.xuexiang.xhttp2.exception.ApiExceptionHandler.handleException(ApiExceptionHandler.java:51)
at com.xuexiang.xhttp2.transform.func.HttpResponseThrowableFunc.apply(HttpResponseThrowableFunc.java:34)
at com.xuexiang.xhttp2.transform.func.HttpResponseThrowableFunc.apply(HttpResponseThrowableFunc.java:31)
at io.reactivex.internal.operators.observable.ObservableOnErrorNext$OnErrorNextObserver.onError(ObservableOnErrorNext.java:91)
at io.reactivex.internal.observers.BasicFuseableObserver.onError(BasicFuseableObserver.java:100)
at io.reactivex.internal.observers.BasicFuseableObserver.onError(BasicFuseableObserver.java:100)
at retrofit2.adapter.rxjava2.BodyObservable$BodyObserver.onError(BodyObservable.java:77)
at retrofit2.adapter.rxjava2.CallExecuteObservable.subscribeActual(CallExecuteObservable.java:60)
at io.reactivex.Observable.subscribe(Observable.java:12284)
at retrofit2.adapter.rxjava2.BodyObservable.subscribeActual(BodyObservable.java:35)
at io.reactivex.Observable.subscribe(Observable.java:12284)
at io.reactivex.internal.operators.observable.ObservableMap.subscribeActual(ObservableMap.java:32)
at io.reactivex.Observable.subscribe(Observable.java:12284)
at io.reactivex.internal.operators.observable.ObservableMap.subscribeActual(ObservableMap.java:32)
at io.reactivex.Observable.subscribe(Observable.java:12284)
at io.reactivex.internal.operators.observable.ObservableOnErrorNext.subscribeActual(ObservableOnErrorNext.java:38)
at io.reactivex.Observable.subscribe(Observable.java:12284)
at io.reactivex.internal.operators.observable.ObservableSubscribeOn$SubscribeTask.run(ObservableSubscribeOn.java:96)
at io.reactivex.Scheduler$DisposeTask.run(Scheduler.java:578)
at io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:66)
at io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:57)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:272)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
Caused by: java.io.FileNotFoundException: /storage/emulated/0/Android/data/com.xuexiang.templateproject/cache/XQRCode_1652508557266.png (No such file or directory)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.(FileInputStream.java:146)
at okio.Okio.source(Okio.kt:194)
at okhttp3.RequestBody$3.writeTo(RequestBody.java:119)
at com.xuexiang.xhttp2.request.body.UploadProgressRequestBody.writeTo(UploadProgressRequestBody.java:87)
at okhttp3.MultipartBody.writeOrCountBytes(MultipartBody.java:173)
at okhttp3.MultipartBody.writeTo(MultipartBody.java:114)
at okhttp3.internal.http.CallServerInterceptor.intercept(CallServerInterceptor.java:72)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
at com.xuexiang.xhttp2.interceptor.NoCacheInterceptor.intercept(NoCacheInterceptor.java:36)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:45)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorC
E/[XHttp]: hain.java:121)
at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:127)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
at com.xuexiang.xhttp2.interceptor.HeadersInterceptor.intercept(HeadersInterceptor.java:56)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
at com.xuexiang.xhttp2.interceptor.NoCacheInterceptor.intercept(NoCacheInterceptor.java:36)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
at com.xuexiang.xhttp2.interceptor.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.java:110)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:257)
at okhttp3.RealCall.execute(RealCall.java:93)
at retrofit2.OkHttpCall.execute(OkHttpCall.java:204)
at retrofit2.adapter.rxjava2.CallExecuteObservable.subscribeActual(CallExecuteObservable.java:46)
... 18 more

你好,请问我上传图片如何使用生命周期绑定?

   XHttp.get("/face/statistics")
            .syncRequest(false) //异步请求
            .onMainThread(true)
            //回到主线程
            .execute(object : CallBackProxy<CustomApiResult<FaceInfoBean>, FaceInfoBean>(object :TipRequestCallBack<FaceInfoBean>() {
                override fun onSuccess(response: FaceInfoBean?) {
                     Log.i("TAG", "请求成功:" + response)

                }

            }) {})

目前我使用这种方式上传图片是没有问题的,请问如何使用 .compose(RxLifecycle.with(this).bindToLifecycle())方式上传图片,请解答下,谢谢

希望提供限流支持

部分业务场景做下载时,防止带宽被完全占用,需要做限流,当前框架不支持,希望可以改进

无法解析接收的JSON中字符串格式日期

在使用XHttp2 POST请求接收JSON数据时,若数据中带有字符串时间,则无法成功

com.github.xuexiangjys:XHttp2:2.0.4

截图
image
image

设备信息
IDEA 2021.3.1 模拟器Pixel XL api 24

附加信息
在此处添加任何有关该问题的任何其他说明。

关于ApiResultFunc 自定义ApiResult 解析时可能存在错误

在调试时发现 ApiResultFunc 类 apply() 方法,line:74 总是执行自定义 ApiResult 的解析。并且内部解析方法 解析会错误。
走默认ApiResult的解析则 Success ,

public ApiResult<T> apply(ResponseBody responseBody) throws Exception {
        ApiResult<T> apiResult = new ApiResult<>();
        apiResult.setCode(-1);
        if (mType instanceof ParameterizedType) {
            // 自定义ApiResult
            apiResult = parseCustomApiResult(responseBody, apiResult);
        } else {
            // 默认ApiResult
            apiResult = parseApiResult(responseBody, apiResult);
        }
        return apiResult;
    }

if (mType instanceof ParameterizedType) 这个条件判断 应该 alwasy true 吧? 不管是使用自定义的那种post 方式, 还是直接使用 XHttp.post() 内部默认的方式。 条件每次都会默认走进这里执行。

tips:
我项目中 code = 1 为成功, 修改了下代码,调试了一番。使用默认 ApiResult 解析逻辑可以解析成功。

比较喜欢你的系列的类库,上手ing

下载请求

发现了一个小小小的问题:
在【DownloadRequest】下载请求中,环境在线程冲中并不能【mIsSyncRequest == true】使用同步的请求;
假如当前环境处于【自定义线程池】中,正在下载大文件的时候,网络发生闪断或者文件服务器突然关闭,订阅者就会有概率接收不到由【AsyncTimeout】抛出的【InterruptedIOException异常】,而导致卡死

PS:
1.当然这种情况只是偶然,并不一定发生,【大概率会抛出:connection reset 异常】
2.关于同步请求,小弟有个小建议:可以使用【CountDownLatch】辅助类喔

image

xhttp2下载问题

$~T073D6$@G43@3GBMH(VL3

多个客户端同事下载一个50m文件,有的客户端35%就停止了,请教大佬可能是什们问题呢

使用中问题和解决方法记录

自定义Result

可能遇到的问题:

  1. ApiResult.class.isAssignableFrom(cls)err!! 原因类被混淆了 需要添加 -keep class 路径
  2. 返回code为不是int类型;
    解决当然是 新建一个枚举映射类啊HttpResponseCode
public class CustomApiResult<T> extends ApiResult<T> {

    private String errorCode;
    private String errorMessage;
    private String requestId;
    private Boolean success;
    private String timestamp;

     //省略get set....

    @Override
    public int getCode() {
        return HttpResponseCode.transServerCode(errorCode);
    }

    @Override
    public String getMsg() {
        return errorMessage;
    }

    @Override
    public boolean isSuccess() {
        return success;
    }

    @Override
    public CustomApiResult setData(T data) {
        super.setData(data);
        return this;
    }

    @Override
    public T getData() {
        return super.getData();
    }

    @Override
    public String toString() {
        return "CustomApiResult{" +
                "code='" + super.getCode() + '\'' +
                ", message='" + super.getMsg() + '\'' +
                ", result=" + super.getData() +
                '}';
    }
}




public enum HttpResponseCode {
    //成功code
    SUCCESS_CODE("0000", 200),
    //未绑定店铺
    NO_SHOP_ERROR_CODE("A0001", 201),
    //需要验证码
    NEED_LOGIN_CODE("A0211", 202);

    HttpResponseCode(String serverCode, int pdaCode) {
        this.serverCode = serverCode;
        this.pdaCode = pdaCode;
    }

    private String serverCode;
    private int pdaCode;

    public String getServerCode() {
        return serverCode;
    }

    public int getPdaCode() {
        return pdaCode;
    }

    public static int transServerCode(String serverCode) {
        for (HttpResponseCode code : HttpResponseCode.values()) {
            if (code.getServerCode().equals(serverCode)) {
                return code.getPdaCode();
            }
        }
        return 0;
    }
}

重要事情说三遍

别忘了 添加 : -keep class CustomApiResult 路径

别忘了 添加 : -keep class CustomApiResult 路径

别忘了 添加 : -keep class CustomApiResult 路径

返回 的Data 不是一个JsonObject是String Long 等类型

{
    "errorCode": "00000",
    "errorMessage": null,
    "data": "rsapublckkey",
    "requestId": "xfdf22121s",
    "success": true
}




//此处以String为例子
XHttp.get("/web/auth/getEncryptKey")
			.execute(new CallBackProxy<CustomApiResult<String>, String>(new SimpleCallBack<String>() {
				@Override
				public void onSuccess(String responseString) throws Throwable {
				//这里的responseString 为 上面的整个后台返回报文
				ApiResponse response = GSONUtil.parseStringData(responseString, ApiResponse.class);
				//然后  类型自己转 判空啥的 注意
				String a = response.getData(),toSting();
				}
			}){});  //千万注意,这里的{}一定不能去掉,否则解析错误


//lombok插件
@Data
public class ApiResponse implements Serializable {
    private String errorCode;
    private String errorMessage;
    private String requestId;
    private Boolean success;
    private Object data;
 
}

动态添加参数的拦截器遇到的坑

添加token 时当token 包含特殊字符 如 空格 等 会转义导致后台校验token失败
解决:不使用拦截器添加;在XHttp.get("") 或者XHttp.post("")是添加Header;
在自己项目里 对 XHttp.get("") ;post等请求 再封装一层,在这里添加Header 等其他操作

Cookie

    XHttp.getInstance().setCookieStore(CookieManager.getInstance(application));

反正我这一行代码就解决 了;

其他走代理的请求 没用过 没试过;

NetMethod能否支持设置hearder参数哈

提Bug前需要做的事情

1.如果是集成问题的话,请保证仔细按照如何引用的步骤,一步一步来,不要跳步骤!
2.详细阅读过使用手册,并且确保是框架的问题。

如果以上都不能解决你的问题,那么请按照以下说明仔细填写信息,这里需要说明的是:不符合填写要求的issue一律不予理会,希望这样能节约大家的时间!


问题描述(必填)
你好,这个框架用着很不错,请问一下NetMethod注解能否支持设置hearder参数呀,有时候需要动态设置头部参数(当然我知道直接调用Xhttp.post().headers("","")这种方式是可以动态设置headers),只是希望NetMethod注解的这种方式也能支持呢,谢谢

使用的XHttp2版本(必填)
2.0.4

期望的效果
NetMethod注解的这种方式也能支持设置hearders

附加信息
不是bug,只是小小建议哈

请求失败: 首页数据获取成功

`log里看着请求成功了,打印了返回的数据,但是走了OnError()方法。。。用的内置的通用请求,返回数据格式符合要求,Data,Msg,Code

如何同步获取网络请求结果

XHttp.get(baseUrl + "/api/GetDeviceNo")
.params("imei",imei)
.keepJson(true)
.syncRequest(true)
.execute(String.class)
.subscribe(new TipRequestSubscriber() {
@OverRide
protected void onSuccess(String res) {
orderNo = res.replace(""","");
Log.e("GetOrderNo", "onSuccess: orderNo=" + orderNo);
}

                @Override
                public void onError(ApiException e) {
                    Log.e("GetOrderNo", "onError: ex =" + e.getMessage() );
                }
            });

报如下错误
W/System.err: android.os.NetworkOnMainThreadException
W/System.err: at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1288)

可以画个框架设计图吗

还有个问题,设计Xhttp.get(url) 这种封装,和直接使用Okhttp提供的请求方式类似, Retrofit将路径和请求解耦,这种哦反向封装有必要吗

自定义API请求的话,如果有和默认的json的某个key一样的话,异常:定义多个json字段的exception

其他时候正常,自定义API请求的话,如果有和默认的json的某个key一样的话,
比如服务端返回的是:

{
        "success": true,
        "errorCode": "-1",
        "msg": "登录成功!",
        "body": {xxx}
}

会抛出异常declares multiple JSON fields named msg
但如果在自定义的ApiResult中不定义msg的话,重写父类的getMsg方法。如果返回结果successtrue的话,正常调用onSuccess;如果返回结果不是true,就会走onError。抛出ApiExceptiondetailMessagemsg的内容。

不知道是我食用姿势不对还是咋的。

返回其它的的json的话,正常使用。。。。。。

文件下载开始后如何能够在update的回调中停止下载?

问题描述(必填)
问题:使用XHttp.downLoad方法进行下载文件,我需要在下载的update回调中停止下载,要调用什么方法能停止呢?

使用的XHttp2版本(必填)
版本:xhttp2 = "2.0.4"

如何重现(必填)

XHttp.downLoad(serverUrl + ApiConstant.API_FILE_DOWN + programResource.getResourceId())
                .savePath(MyApp.CACHE_RESOURCE_PATH)
                .saveName(fileName)
                .execute(new DownloadProgressCallBack<String>() {
                    @Override
                    public void onStart() {
                        XLogger.e("onStart");
                    }

                    @Override
                    public void onError(ApiException e) {
                        //这里想要停止这个下载,要如何停止??????????
                        
                    }

                    @Override
                    public void update(long bytesRead, long contentLength, boolean done) {
                    }

                    @Override
                    public void onComplete(String path) {

                    }
                });

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.