Coder Social home page Coder Social logo

xiaoyaoyou1212 / xsnow Goto Github PK

View Code? Open in Web Editor NEW
1.7K 53.0 390.0 20.92 MB

💮基于RxJava2+Retrofit2精心打造的Android基础框架,包含网络、上传、下载、缓存、事件总线、权限管理、数据库、图片加载,基本都是项目中必用功能,每个模块充分解耦,可自由拓展。

Home Page: http://www.huwei.tech/

License: Apache License 2.0

Java 99.97% Batchfile 0.03%
rxjava2 retrofit2 rxbus rxpermissions cache glide greendao

xsnow's Introduction

Anurag's GitHub stats

xsnow's People

Contributors

xiaoyaoyou1212 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

xsnow's Issues

异常信息

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 怎么处理呢?现在大部分接口,都是一个baseUrl,我直接在application中配置就可以了。但是有的接口,需要另一个baseUrl,如此一来,让我不知怎么办了。麻烦博主,指教一下吧,谢谢!

局部配置超时时间配置代码调用api有误

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);
}

2.1.9版本 解决自定义ApiException 响应处理返回code的方法

应用场景: 当服务器返回 类似 { “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;
}

至此,便可成功响应服务器返回码。
附上我的最终处理结果。
image
最后,由衷感谢博主提供的开源框架。

拦截器有关问题

请问一下楼主,在哪里可以拦截到请求的地址,参数等信息呢,HttpLogInterceptor这个里面只能看到地址的请求方式呢。

通过添加头信息addhead token验证,无效不起作用

`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);
        }
    });`

4G 网络请求失败

所用的请求,只有在wifi下才能请求成功,4G网络下请求失败~

一点小小建议

建议使用mvp模式或者mvvm模式 然后在Application里面定义统一异常处理 现在控件一般几乎不会去findViewById直接用butterknife 网络这一块可以用开源的api来实现一个demo即可 然后重点讲一下加密请求就可以啦 上传和下载一般小型app用得不多 根据自己需求来加就ok了 暂时就这些

使用缓存的时候报错;Application和具体调用的配置如下;

日志: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 的问题

我看到 BaseActivity 里面有个 mViews 用来缓存 View ,我感觉没什么用啊,在用的时候肯定是 find 完了存下来,你这样再存到 BaseActivity 里面缓存一遍,使用频度比较低吧,还是说有什么别的用途

关于xpand扩展中的问题

为何ResponseHelper这个返回帮助列中,isSuccess方法中,ignoreSomeIssue部分也是为true,这不该是返回token方面异常失效情况嘛,为何也是true? 因为HttpResponseInterceptor响应拦截需要?那这样的话,其他错误不是在ApiDataFunc( ApiResult转T)全部返回null了啊? 这一串如何理解呢,谢谢

下载速度太快导致下载失败

这是一个尴尬的问题哈~

当下载速度大概大于1500KB/s时,会导致下载失败,原因:
rx.exceptions.MissingBackpressureException
当下载速度过快时,所发射数据快于处理数据的速度,就会出现这个问题。

ApiDataFunc中处理服务器响应码的问题

代码如下:

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处理吧. 真实人才啊.

CookiesStore.java 可能会有问题

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"

ApiResult的list泛型转换问题

有以下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转换失败。

这个问题如何解决呢?

retrofit自定义请求问题

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 这个类怎么用

HttpResponseInterceptor 这个类怎么用。现在我想处理AccessToken错误或已过期、帐号在其它手机已登录等等这些操作,但是这些操作是放在UI层的,怎么设计会好一点

编译报错?

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:

In the case of corrupt Gradle processes, you can also try closing the IDE and then killing all Java processes.

登录时设置的全局请求头token 当应用处于后台长时间挂起,回到前台时token会失效

@xiaoyaoyou1212 登录时设置的全局token 当应用处于后台长时间挂起,回到前台时token会失效,实际上webapi后台token的存活时间是一天,也就是说长时间处于后台全局请求头会被系统回收,导致请求没有token,把token保存在sp中做判断重新设置token也没用, 把请求头定义成静态变量也没用! 后台时间长了一样会被系统回收

rxBus注解问题

如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 这个接受事件注解类呢?

是否应该把Retrofit从Request中抽离出来更好?

大概地看了2.0版本的网络模块,相对于1.0版本,2.0版本灵活度更高功能也更完善了。但在看到BaseRequest#generateLocalConfig这里,总感觉怪怪的:这意味着每一次网络请求,都会新建一个Retrofit对象,但其实每一个Retrofit的config其实是一样的(baseUrl == null时)。所以我觉得每一次新建一个Retrofit是非必要的。

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.