xiaoyaoyou1212 / xsnow Goto Github PK
View Code? Open in Web Editor NEW💮基于RxJava2+Retrofit2精心打造的Android基础框架,包含网络、上传、下载、缓存、事件总线、权限管理、数据库、图片加载,基本都是项目中必用功能,每个模块充分解耦,可自由拓展。
Home Page: http://www.huwei.tech/
License: Apache License 2.0
💮基于RxJava2+Retrofit2精心打造的Android基础框架,包含网络、上传、下载、缓存、事件总线、权限管理、数据库、图片加载,基本都是项目中必用功能,每个模块充分解耦,可自由拓展。
Home Page: http://www.huwei.tech/
License: Apache License 2.0
ViseHttp.POST("login")
.baseUrl("http://121.41.44.177/")
.addParam("mobile", "152502016")
.addParam("password", "wrewefa")
.request(new ACallback() {
@OverRide
public void onFail(int errCode, String errMsg) {
ViseLog.e("request errorCode:" + errCode + ",errorMsg:" + errMsg);
}
@Override
public void onSuccess(String data) {
ViseLog.i("request onSuccess!" + data);
mShow_response_data.setText(data);
}
});
应用场景: 当服务器返回 类似 { “code”:400, "message:"用户不存在"} 这样的返回数据,调用demo的 ViseHttp.POST, 返回的exception 为: code :1000, msg: UNKNOWN。 这明显与我们预期的返回:“用户不存在” 提示有冲突。请问大佬这应该怎么去改呢?
现在公司采用了,您的网络框架。请问博主,如果我想配置多个 baseUrl 怎么处理呢?现在大部分接口,都是一个baseUrl,我直接在application中配置就可以了。但是有的接口,需要另一个baseUrl,如此一来,让我不知怎么办了。麻烦博主,指教一下吧,谢谢!
package com.vise.xsnow.http.request;
该类中,generateLocalConfig()方法中,配置超时时间api有误,全部设置的都是连接服务器后的读取时间,在局部配置修改超时时间不生效:
if (readTimeOut > 0) {
newBuilder.readTimeout(readTimeOut, TimeUnit.SECONDS);
}
if (writeTimeOut > 0) {
//应调用newBuilder.writeTimeout(writeTimeOut, TimeUnit.SECONDS);
newBuilder.readTimeout(writeTimeOut, TimeUnit.SECONDS);
}
if (connectTimeOut > 0) {
//应调用 newBuilder.connectTimeout(connectTimeOut, TimeUnit.SECONDS);
newBuilder.readTimeout(connectTimeOut, TimeUnit.SECONDS);
}
应用场景: 当服务器返回 类似 { “code”:400, "message:"用户不存在"} 这样的返回数据,调用demo的 ApiPostRequest, 返回的exception 为: code :1000, msg: UNKNOWN。 这明显与我们预期的返回:“用户不存在” 提示有冲突。
解决方法: 参考了该#2 issues 的解决思路
代码如下:
1、修改ApiBaseRequest
`protected ObservableTransformer<ApiResult, T> apiTransformer() {
return new ObservableTransformer<ApiResult<T>, T>() {
@Override
public ObservableSource<T> apply(Observable<ApiResult<T>> apiResultObservable) {
return apiResultObservable
.subscribeOn(Schedulers.io())
.unsubscribeOn(Schedulers.io())
.flatMap(new Function<ApiResult<T>, Observable<T>>() {
@Override
public Observable<T> apply(ApiResult<T> tApiResult) throws Exception {
if (ResponseHelper.isSuccess(tApiResult)) {
return Observable.just(tApiResult.getData());
} else {
ApiException e = new ApiException(new Throwable(tApiResult.getMsg()), tApiResult.getCode());
return Observable.error(e);
}
}
})
.observeOn(AndroidSchedulers.mainThread())
.retryWhen(new ApiRetryFunc<T>(retryCount, retryDelayMillis));
}
};
}`
2、在ApiException文件,新增内容:
else if (e instanceof ApiException){
ex = new ApiException(e, ((ApiException) e).getCode());
ex.message = e.getLocalizedMessage();
return ex;
}
如题。
请问一下楼主,在哪里可以拦截到请求的地址,参数等信息呢,HttpLogInterceptor这个里面只能看到地址的请求方式呢。
ApiPostRequest这个是要自己写吗?
`ViseHttp.GET("api/Report/Get7DayFpyRate")
.addParam("sid", "5")
.addParam("lineId", "431")
.addParam("acctId", "1")
.addHeader("Authorization", "Bearer "+token.trim())
.addHeader("Content-Type","application/json;charset=utf-8")
.request(new ACallback() {
@OverRide
public void onSuccess(Get7DayFpyRateResponse data) {
}
@Override
public void onFail(int errCode, String errMsg) {
ToastUtils.showShort("errCode: "+errMsg+" errMsg: "+ errMsg);
}
});`
所用的请求,只有在wifi下才能请求成功,4G网络下请求失败~
设置为0或者注释掉还是有4次重试
建议使用mvp模式或者mvvm模式 然后在Application里面定义统一异常处理 现在控件一般几乎不会去findViewById直接用butterknife 网络这一块可以用开源的api来实现一个demo即可 然后重点讲一下加密请求就可以啦 上传和下载一般小型app用得不多 根据自己需求来加就ok了 暂时就这些
日志:io.reactivex.exceptions.ProtocolViolationException: It is not allowed to subscribe with a(n) httplibrary.http.subscriber.ApiCallbackSubscriber multiple times. Please create a fresh instance of .httplibrary.http.subscriber.ApiCallbackSubscriber and subscribe that to the target source instead.
.setHttpCache(true) //配置OkHttp缓存路径 .setHttpCacheDirectory(new File(WeiShuHttp.getContext().getCacheDir(), HttpConfig.CACHE_HTTP_DIR))
Http.BASE(new ApiGetRequest(HttpUrl.Algorithm.algorithmSetting + "/" + BaseApplication.getUserId())) .addHeader("token", BaseApplication.getToken()) .setLocalCache(true) .cacheMode(CacheMode.FIRST_CACHE) .request(new ACallback<RpParamModel>() { @Override public void onSuccess(RpParamModel data) {
我看到 BaseActivity 里面有个 mViews 用来缓存 View ,我感觉没什么用啊,在用的时候肯定是 find 完了存下来,你这样再存到 BaseActivity 里面缓存一遍,使用频度比较低吧,还是说有什么别的用途
为何ResponseHelper这个返回帮助列中,isSuccess方法中,ignoreSomeIssue部分也是为true,这不该是返回token方面异常失效情况嘛,为何也是true? 因为HttpResponseInterceptor响应拦截需要?那这样的话,其他错误不是在ApiDataFunc( ApiResult转T)全部返回null了啊? 这一串如何理解呢,谢谢
这是一个尴尬的问题哈~
当下载速度大概大于1500KB/s时,会导致下载失败,原因:
rx.exceptions.MissingBackpressureException
当下载速度过快时,所发射数据快于处理数据的速度,就会出现这个问题。
代码如下:
public class ApiDataFunc<T> implements Func1<ApiResult<T>, T> {
public ApiDataFunc() {
}
@Override
public T call(ApiResult<T> response) {
if (ApiException.isSuccess(response)) {
return response.getData();
} else {
return (T) new ApiException(new Throwable(response.getMsg()), response.getCode());
}
}
}
在call方法里,如果ApiException.isSuccess(response)为false,直接走else里的逻辑:
return (T) new ApiException(new Throwable(response.getMsg()), response.getCode());
上面这一行代码中,ApiException强转T,肯定会出现异常,这个异常发生后,接着在ApiErrFunc处理:
public class ApiErrFunc<T> implements Func1<Throwable, Observable<T>> {
@Override
public Observable<T> call(Throwable throwable) {
return Observable.error(ApiException.handleException(throwable));
}
}
最后抛出到Subscriber.onError()。
现在问题是,在onError()收到的并不是我们期望的包含response信息的ApiException,而只是一个类型转换错误的Throwable
public static ApiException handleException(Throwable e) {
ApiException ex;
if (e instanceof HttpException) {
HttpException httpException = (HttpException) e;
ex = new ApiException(e, ApiCode.Request.HTTP_ERROR);
switch (httpException.code()) {
case ApiCode.Http.UNAUTHORIZED:
case ApiCode.Http.FORBIDDEN:
case ApiCode.Http.NOT_FOUND:
case ApiCode.Http.REQUEST_TIMEOUT:
case ApiCode.Http.GATEWAY_TIMEOUT:
case ApiCode.Http.INTERNAL_SERVER_ERROR:
case ApiCode.Http.BAD_GATEWAY:
case ApiCode.Http.SERVICE_UNAVAILABLE:
default:
ex.message = "NETWORK_ERROR";
break;
}
return ex;
}
这段代码真的不是在作死吗?? 限制了对网络错误的处理. 作为框架应该是去开放功能,而不是去乱限制前端的UI处理吧. 真实人才啊.
自定义的Retrofit请求cacheKey每一次都是同一个,是不是需要每次请求手动设置不一样的cacheKey呢?
if (cookie.persistent()) {//需要持久化
//将cookies持久化到本地
prefsWriter.putString(url.host(), TextUtils.join(",", cookies.get(url.host()).keySet()));
prefsWriter.putString(name, encodeCookie(new OkHttpCookies(cookie)));
prefsWriter.apply();
} else {//不需要持久化
prefsWriter.remove(url.host());
prefsWriter.remove(name);
prefsWriter.apply();
}
这段代码,会导致所需的cookie 丢失
发起网络请求,在请求结果返回前页面就已经销毁了,框架中是怎么处理的?
ApiResultFunc中String类型需要单独处理,我看了ApiFunc中有处理,为什么ApiResultFunc中不加入处理呢,实测会引起类型转换异常,"期望String,实际是一个Object"
有以下Json字符串:
{
"code": 404,
"data":
{
"age": 27,
"name": "qinicy"
},
"msg": "success"
}
User的Model:
public class User implements Serializable{
@SerializedName("name")
public String name;
@SerializedName("age")
public int age;
}
以下是正常的:
mViseApi.apiGet("http://192.168.199.171:3000/user/", new HashMap<String, String>(), new ApiCallback<User>() {
@Override
public void onStart() {
LogUtil.d("onStart");
}
@Override
public void onError(ApiException e) {
LogUtil.d("onError");
}
@Override
public void onCompleted() {
LogUtil.d("onCompleted");
}
@Override
public void onNext(User user) {
LogUtil.d("onNext");
}
});
如果Json变成这样:
{
"code": 0,
"data": [
{
"age": 27,
"name": "qinicy"
},
{
"age": 20,
"name": "Bing"
}
],
"msg": "success"
}
如何正确获取得到List?
以下不可行:
mViseApi.apiGet("http://192.168.199.171:3000/user/", new HashMap<String, String>(), new ApiCallback<List<User>>() {
@Override
public void onStart() {
LogUtil.d("onStart");
}
@Override
public void onError(ApiException e) {
LogUtil.d("onError");
}
@Override
public void onCompleted() {
LogUtil.d("onCompleted");
}
@Override
public void onNext(List<User> userList) {
LogUtil.d("onNext");
}
});
这是由于内部逻辑中:
ClassUtil.getTClass(callback))
得到的Class并不是期望的List,而是User,从容导致最后Gson转换失败。
这个问题如何解决呢?
ViseHttp.RETROFIT()
.create(AuthorService.class)
.getAuthor()
.compose(ApiTransformer.norTransformer())
.subscribe(new ApiCallbackSubscriber<>(new ACallback() {
@OverRide
public void onSuccess(AuthorModel authorModel) {
ViseLog.i("request onSuccess!");
if (authorModel == null) {
return;
}
mShow_response_data.setText(authorModel.toString());
}
@Override
public void onFail(int errCode, String errMsg) {
ViseLog.e("request errorCode:" + errCode + ",errorMsg:" + errMsg);
}
}));
retrofit自定义请求通过拦截器查看是成功的,但是回调走了onFail 方法,这是什么原因呢?
HttpResponseInterceptor 这个类怎么用。现在我想处理AccessToken错误或已过期、帐号在其它手机已登录等等这些操作,但是这些操作是放在UI层的,怎么设计会好一点
如题,目前看代码以及实测都是在主线程中,可能楼主没有处理过5M左右的json,所以个人认为这是很有必要的改善
ApiCode里面的请求码用不上,我需要添加新的请求码参数。直接改吗?
Error:org.gradle.api.internal.tasks.DefaultTaskInputs$TaskInputUnionFileCollection cannot be cast to org.gradle.api.internal.file.collections.DefaultConfigurableFileCollection
Possible causes for this unexpected error include:
@xiaoyaoyou1212 登录时设置的全局token 当应用处于后台长时间挂起,回到前台时token会失效,实际上webapi后台token的存活时间是一天,也就是说长时间处于后台全局请求头会被系统回收,导致请求没有token,把token保存在sp中做判断重新设置token也没用, 把请求头定义成静态变量也没用! 后台时间长了一样会被系统回收
作者你好,针对多个baseurl情况有没有啥好的处理~
如题:如何取消掉当前正在执行的网络请求?
在开发中想看日志
如demo中所示:同一个AuthorEvent对象,但是post发送参数也都是AuthorEvent,如果我有两个接受不同的事件(携带的都是AuthorEvent,但是要做的是不一样的,怎么区分);
因此,我想起,post可以携带参数发送,即post("tag",AuthorEvent);但是我发现你这个框架中,接收事件注解类
@retention(RetentionPolicy.RUNTIME)
@target(ElementType.METHOD)
public @interface Subscribe {
ThreadMode threadMode() default ThreadMode.MAIN_THREAD;
}
有问题,
@subscribe 后面没法添加(“tag”),编译报错,请问如何修改 @interface Subscribe 这个接受事件注解类呢?
大概地看了2.0版本的网络模块,相对于1.0版本,2.0版本灵活度更高功能也更完善了。但在看到BaseRequest#generateLocalConfig这里,总感觉怪怪的:这意味着每一次网络请求,都会新建一个Retrofit对象,但其实每一个Retrofit的config其实是一样的(baseUrl == null时)。所以我觉得每一次新建一个Retrofit是非必要的。
感觉轮子不错,想学习一下,可以分析一下么,楼楼
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.