前言
上一个文章【Android 开发框架搭建】-网络框架三剑客Okhttp+Rxjava+Retrofit介绍了Android如何搭建轻量级Okhttp+Rxjava+Retrofit网络框架,此篇文章介绍该框架高级功能使用
高级使用
这里介绍框架高级功能使用方式
1.使用RxCache
此组件官方概述: 就像Picasso 缓存您的图片一样,毫不费力缓存您的数据对象。
每个Android Application都是一个客户端应用程序,这意味着仅仅为缓存数据创建数据库并进行维护毫无意义。
事实上,传统方式通过数据库来缓存数据并没有解决根本性的问题:以更加灵活简单的方式配置缓存。
灵感来源于 Retrofit , RxCache是一个用于Android和Java的响应式缓存库,它可将您的缓存需求转换为一个接口进行配置。
当提供一个 observable, single, maybe or flowable (这些是RxJava2支持的响应式数据类型) 这些由耗时操作提供的数据,RxCache确定是否需要subscribe,或覆盖先前缓存的数据。
此决定是基于RxCache的Providers进行配置的。
该组件详细使用方式可参考官方Github文档,此处只会简单结束框架如何使用该组件。
注:使用该组件必须依赖Rxjava库,本框架上篇文章中已经添加过该依赖
Github传送门
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| api "com.github.VictorAlbertos.RxCache:runtime:1.8.3-2.x" api "com.github.VictorAlbertos.Jolyglot:gson:0.0.4"
public class MyApplication extends Application { @Override public void onCreate() { super.onCreate();
new NetworkLoader.Build(this) .setBaseUrl("项目正式地址","项目测试地址") .setLogLevel(HttpLoggingInterceptor.Level.HEADERS) .setOpenCache(true) .setOpenRxCache(true) .setNetworkHeaderParams(new TokenParams()) .setResponseErrorListener(new CustomResponseErrorListenerImpl()) .create().build(); } }
|
在项目中搭建RxCache相关类
@ProviderKey 定义数据缓存的key
@LifeCache 定义缓存时间策略
其它注解使用请参考官方介绍,上方有传送门
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
|
public interface TestRxCacheController { @ProviderKey("app-net-top") @LifeCache(duration = 5, timeUnit = TimeUnit.MINUTES) Observable<BaseApiResult<String>> getTop(Observable<BaseApiResult<String>> top); }
public interface TestService {
Observable<BaseApiResult<String>> getTop();
}
public class TestRxCacheServiceImpl extends BaseRxCacheServiceImpl<TestRxCacheController> implements TestService {
private static TestRxCacheServiceImpl instance = null;
private TestRxCacheServiceImpl() { super(TestRxCacheController.class); }
public static TestRxCacheServiceImpl getInstance() { if (instance == null) { synchronized (TestRxCacheServiceImpl.class) { if (instance == null) { instance = new TestRxCacheServiceImpl(); } } } return instance; }
@Override public Observable<BaseApiResult<String>> getTop() { return getApi().getTop(TestServiceImpl.getInstance().getTop()).compose(RxBus.ApplySchedulers()); } }
TestRxCacheServiceImpl.getInstance().getTop().subscribe(data -> { Log.e("MainActivity", "subscribe: "+JSON.toJSONString(data)); }, throwable -> { Log.e("MainActivity", "onCreate: ", throwable); });
public class BaseRxCacheServiceImpl<RxCacheController> {
private RxCacheController rxCacheController;
public BaseRxCacheServiceImpl(Class<RxCacheController> clazz) { try { rxCacheController = NetworkLoader.getInstance().getRxCache().using(clazz); }catch (Exception e){ Log.e(NetworkLoader.TAG, "RxCacheError: 配置网络框架时未开启RxCache配置,请检查" ); } }
protected RxCacheController getApi() { return rxCacheController; }
}
|
2.使用Rxerrorhandler
Rxjava异常错误处理类,定义统一的异常处理接口
Github传送门
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
| api "me.jessyan:rxerrorhandler:2.1.1"
public class MyApplication extends Application { @Override public void onCreate() { super.onCreate();
new NetworkLoader.Build(this) .setBaseUrl("项目正式地址","项目测试地址") .setLogLevel(HttpLoggingInterceptor.Level.HEADERS) .setOpenCache(true) .setOpenRxCache(true) .setNetworkHeaderParams(new TokenParams()) .setResponseErrorListener(new CustomResponseErrorListenerImpl()) .create().build(); } }
public class CustomResponseErrorListenerImpl extends BaseResponseErrorListenerImpl {
@Override public void handleResponseError(Context context, Throwable t) { super.handleResponseError(context, t);
} }
public class BaseResponseErrorListenerImpl implements ResponseErrorListener {
@SuppressLint("ShowToast") @Override public void handleResponseError(Context context, Throwable t) { Log.e(NetworkLoader.TAG, "RxError 捕获", t); String msg = "未知错误"; if (t instanceof UnknownHostException) { msg = "网络不可用"; } else if (t instanceof SocketTimeoutException) { msg = "请求网络超时"; } else if (t instanceof HttpException) { HttpException httpException = (HttpException) t; msg = convertStatusCode(httpException); } else if (t instanceof JsonParseException || t instanceof ParseException || t instanceof JSONException || t instanceof JsonIOException) { msg = "数据解析错误"; } Toast.makeText(context, msg, Toast.LENGTH_SHORT); }
private String convertStatusCode(HttpException httpException) { String msg; if (httpException.code() == 500) { msg = "服务器发生错误"; } else if (httpException.code() == 404) { msg = "请求地址不存在"; } else if (httpException.code() == 403) { msg = "请求被服务器拒绝"; } else if (httpException.code() == 307) { msg = "请求被重定向到其他页面"; } else { msg = httpException.message(); } return msg; }
}
TestRxCacheServiceImpl.getInstance().getTop().subscribe(new ErrorHandleSubscriber<BaseApiResult<String>>(NetworkLoader.getInstance().getRxErrorHandler()) { @Override public void onNext(@NonNull BaseApiResult<String> longBaseApiResult) { Log.e("MainActivity", "ErrorHandleSubscriber: "+JSON.toJSONString(longBaseApiResult)); } });
|
3.使用Rxpermissions
基于Rxjava编写的Android权限管理库,详细使用参考官方说明
Github传送门
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
|
api "com.github.tbruyelle:rxpermissions:0.10.2"
public class RxPermissionsUtil {
public static Disposable checkPermissionsHandler(@NonNull Fragment fragment, String[] permissionsGroup, Consumer<Boolean> booleanConsumer) { RxPermissions rxPermissions = new RxPermissions(fragment); return rxPermissions.request(permissionsGroup) .subscribe(booleanConsumer::accept); }
public static Disposable checkPermissionsHandler(@NonNull FragmentActivity fragmentActivity, String[] permissionsGroup, Consumer<Boolean> booleanConsumer) { RxPermissions rxPermissions = new RxPermissions(fragmentActivity); return rxPermissions.request(permissionsGroup) .subscribe(booleanConsumer::accept); }
public static void destroyDisposable(Disposable disposable) { if (disposable != null && !disposable.isDisposed()) { disposable.dispose(); } } }
RxPermissionsUtil.checkPermissionsHandler(MainActivity.this, new String[]{Manifest.permission.ACCESS_NETWORK_STATE, Manifest.permission.READ_PHONE_STATE}, new Consumer<Boolean>() { @Override public void accept(Boolean aBoolean) { } });
|
总结
该框架现阶段支持的功能都已介绍完毕,希望能够给大家提供帮助。后续会持续更新框架,添加更多适用于该框架的技术。
框架及Demo源码
源码地址 MiQingWang/CommonNetFrame