如:
BASE:传入自定义请求对象,方便外部根据自己的需求自定义请求;GET:获取 GET 方式请求对象;POST:获取 POST 方式请求对象;HEAD:获取 HEAD 方式请求对象;PUT:获取 PUT 方式请求对象;PATCH:获取 PATCH 方式请求对象;OPTIONS:获取 OPTIONS 方式请求对象;DELETE:获取 DELETE 方式请求对象;UPLOAD:获取上传文件请求对象,支持传入上传回调;DOWNLOAD:获取下载文件请求对象。该类还提供了根据 tag 中断单个网络请求以及中断所有网络请求功能,也提供了根据 key 删除缓存和清除所有网络缓存功能。必须注意的是,在应用初始化时必须调用该类的初始化方法
ViseHttp.init(this); 1 1以及相关的网络配置
ViseHttp.CONFIG() //配置请求主机地址 .baseUrl("http://10.8.4.39/") //配置全局请求头 .globalHeaders(new HashMap<String, String>()) //配置全局请求参数 .globalParams(new HashMap<String, String>()) //配置读取超时时间,单位秒 .readTimeout(30) //配置写入超时时间,单位秒 .writeTimeout(30) //配置连接超时时间,单位秒 .connectTimeout(30) //配置请求失败重试次数 .retryCount(3) //配置请求失败重试间隔时间,单位毫秒 .retryDelayMillis(1000) ......; 123456789101112131415161718 123456789101112131415161718这样才能在应用中调用相关的网络请求功能。如果没有初始化,在调用网络请求时该模块会抛出如下异常信息:
Please call ViseHttp.init(this) in Application to initialize! 1 1切记!
下面来分别讲解该模块下每个包的功能:
api 该包提供的是请求的 API,目前只有一个类 ApiService,主要提供的是 Retrofit 进行网络请求的请求方法。
body 该包提供的是相关的请求和响应 body,目前只有一个上传进度展示的请求实体类 UploadProgressRequestBody,通过传入 UCallback 来处理上传文件的进度回调。
callback 该包提供的是相关的回调类,目前包含上传回调 UCallback 和请求 API 回调 ACallback。
config 该包提供的是配置相关类,目前只有请求全局配置类 HttpGlobalConfig,该类提供了很丰富的配置方法,提供该类的目的是想将配置与请求分离。
core 该包提供的是一些核心功能类,目前包含缓存处理类 ApiCache、Cookie 管理类 ApiCookie 以及网络请求订阅管理类 ApiManager。缓存采用磁盘缓存方式,支持定制各种缓存策略,策略将在 strategy 包下进行讲解。Cookie 采用 SharedPreferences 存储,存储对象以十六进制进行保存。
exception 该包提供网络请求相关异常类,目前提供了请求异常统一处理类 ApiException,可用来判定请求失败的原因。
func 该包提供一些数据转换类,目前提供了由 ResponseBody 对象转 T 的 ApiFunc<T> 类以及由 Observable<? extends Throwable> 转 Observable<?> 的 ApiRetryFunc 类。ApiRetryFunc 类主要用来处理网络超时重试机制,可传入重试次数和重试间隔时间,这些都可以在配置类中进行配置。
interceptor 该包提供的是一系列的拦截器类,这个包也算是该模块的核心包,基本大部分功能都可以采用拦截器的方式来提供,目前该包下面包含如下拦截器: 1、GzipRequestInterceptor:包含Gzip压缩的请求拦截; 2、HeadersInterceptor:请求头拦截; 3、HttpLogInterceptor:Http日志打印拦截; 4、NoCacheInterceptor:无缓存拦截; 5、OfflineCacheInterceptor:离线缓存拦截; 6、OnlineCacheInterceptor:在线缓存拦截; 7、UploadProgressInterceptor:上传文件进度展示拦截。
mode 该包提供的是相关的实体类。
request 该包提供的是所有请求相关的类,所有的网络请求都需要创建一个请求对象,该包提供了一个基础请求类 BaseRequest<R extends BaseRequest>,该类需将 R 写成实际请求类,这样才能获取对应请求类的对象来进行相关的请求信息配置,如果请求配置与全局配置冲突,那么优先请求配置,意思就是局部请求配置会替换掉相同的全局配置。 请求类中提供了一系列请求头配置、请求参数配置等信息,如果是 POST 请求还提供了上传 JSON 字符串、上传表单等方式,而如果是上传文件则提供了添加文件、添加字节数组和添加流的方式。 由于带缓存请求和不带缓存请求返回的结果不一样,所以需要分开处理,故有 cacheExecute 和 execute 的区分。
strategy 该包提供的是缓存相关的策略,包含如下几种策略: 1、CacheAndRemoteStrategy:先加载缓存数据后加载网络数据; 2、FirstCacheStrategy:优先加载缓存数据; 3、FirstRemoteStrategy:优先加载网络数据; 4、OnlyCacheStrategy:只加载缓存数据; 5、OnlyRemoteStrategy:只加载网络数据。 缓存策略采用面向接口编程原则,定义了一个缓存策略接口 ICacheStrategy<T>,并将具体的策略实现交由各个子类。
subscriber 该包提供的是相关的订阅者,目前包含 API 请求的统一订阅者 ApiSubscriber<T>、包含回调的订阅者 ApiCallbackSubscriber<T> 以及包含下载回调的订阅者 DownCallbackSubscriber<T>。
该模块提供了几种缓存方式,分别是内存缓存、磁盘缓存以及 SharedPreferences 存储。该模块主要思想是面向接口编程,提供了 ICache 接口,主要包含添加缓存、获取缓存、删除缓存、清除所有缓存以及判断是否包含该缓存这几个能力。下面将对每个缓存方式做详细的解释说明:
内存缓存:内存缓存采用单例模式管理缓存对象,缓存对象为 LruCache,缓存算法采用 Lru 算法(Least Recently Used 近期最少使用算法),缓存大小为最大内存的八分之一。磁盘缓存:磁盘缓存 KEY 采用 MD5 加密,可定制缓存时长,没有定制则默认永久存储,缓存对象为 DiskLruCache,缓存算法也是 Lru算法,缓存位置和缓存大小都可以定制,如果没有定制就会使用默认值,默认的缓存位置为该应用缓存目录下的 disk_cache 目录,优先存储到 SD 卡中,默认的缓存大小为 20M。SharedPreferences 存储:SharedPreferences 存储对缓存对象进行 Base64 加密存储,可定制缓存文件名,如果没有定制则使用默认文件名 sp_cache。该模块使用 Rx 思想实现了 RxBus 功能,其 Bus 的设计思想与 EventBus 类似。其主要由以下几个核心类组成:
EventBase :事件处理基类,包含粘性事件 Map 以及普通事件 Subject,也定义了获取 Flowable 以及删除粘性事件和删除粘性事件 Map 的方法。EventComposite :事件复合类,就是将需要接收事件的类中所有事件组合到一起进行处理,并提供了一个发送粘性事件的方法。EventSubscriber :事件订阅者,提供了订阅事件和分发事件的方法。EventFind :根据注解查找事件接收方法,由此得到 EventSubscriber,最后组合到一起得到 EventComposite。ThreadMode :线程模型,包含如主线程、IO线程等,通过 getScheduler(ThreadMode thread) 来获取线程调度者。事件接收采用注解方式类进行管理,事件订阅后依据注解来查找对应的事件接收地。
该模块为了能将事件总线统一,定义了 IBus 接口,提供了如下四个方法:
void register(Object object); void unregister(Object object); void post(IEvent event); void postSticky(IEvent event); 1234567 1234567也提供了 IEvent 接口,所有事件都实现该接口,这样就可以将具体的事件实现类抽离,其实也是面向接口编程。
该模块也提供了插件化思想,上层可以将如 EventBus 的实现类注入该模块,那么事件的处理就会采用 EventBus 实现的策略,但这里有一个问题,由于事件接收采用的是注解方式,而 EventBus 中的注解是不同的,所以还是需要把注解事件进行统一替换,耦合性太高,目前没有发现更好的方式,如果哪位朋友有好的去耦合方式,欢迎留言交流!
该模块针对图片加载做了二次封装,面向接口编程,每个实现就是一种图片加载策略,默认采用 Glide 图片加载框架,上层也可以依需自定义实现接口 ILoader,比如 Demo 中提供的 Fresco 图片框架的实现类 FrescoLoader,其主要思想就是插件化,外部可注入任何加载策略,这样可达到高内聚低耦合。
接口中提供了如下四种加载图片的方式:
加载网络图片 void loadNet(ImageView target, String url, Options options); 1 1 加载资源图片 void loadResource(ImageView target, int resId, Options options); 1 1 加载Assets中的图片 void loadAssets(ImageView target, String assetName, Options options); 1 1 加载本地图片 void loadFile(ImageView target, File file, Options options); 1 1默认的 Glide 框架采用 provided 方式依赖,这样就只是编译时依赖,运行时不依赖,上层如果确定使用 GlideLoader加载策略,那么还需要自己使用 compile 进行依赖,这样运行时才不会报错,GlideLoader 在初始化时也增加了如下验证机制
try { Class.forName("com.bumptech.glide.Glide"); } catch (ClassNotFoundException e) { throw new IllegalStateException("Must be dependencies Glide!"); } 12345 12345如果没有依赖 Glide 库则会抛出异常。
该模块将 GreenDao 作为底层数据库,定义了数据库的操作接口 IDatabase<M, K>,统一由 DBManager<M, K> 抽象类管理,由于每个实体类对应的 Dao 不一样,所以定义了抽象方法 getAbstractDao()。由于 GreenDao 的特殊性,该方法的实现类不能在框架中搭建,所有数据库操作都可以参考 Demo 中 DbHeDlper 类实现自己的数据库操作管理类,不同的 Dao 实现对应的 getAbstractDao() 方法就行。
该模块利用 Rx 思想统一管理权限的申请,一行代码搞定权限的申请问题。
PermissionManager.instance().with(this).request(onPermissionCallback, Manifest.permission.CALL_PHONE); 1 1该模块很简洁,就几个类,下面分别对它们进行介绍:
OnPermissionCallback:权限申请回调接口,在接口实现类中调用具体的业务逻辑。Permission:权限实体类,包含权限名称、是否授予权限以及是否显示权限申请理由变量。PermissionManager:权限管理类,也是权限申请的唯一入口,采用单例模式,需要通过 with 将当前的 Activity 对象传进去,调用 request 方法就可以进行权限申请,需要传入回调和权限列表,权限列表采用可变数组方式传入,使用示例如下: PermissionManager.instance().with(this).request(new OnPermissionCallback() { @Override public void onRequestAllow(String permissionName) { DialogUtil.showTips(mContext, getString(R.string.permission_control), getString(R.string.permission_allow) + "\n" + permissionName); } @Override public void onRequestRefuse(String permissionName) { DialogUtil.showTips(mContext, getString(R.string.permission_control), getString(R.string.permission_refuse) + "\n" + permissionName); } @Override public void onRequestNoAsk(String permissionName) { DialogUtil.showTips(mContext, getString(R.string.permission_control), getString(R.string.permission_noAsk) + "\n" + permissionName); } }, Manifest.permission.CALL_PHONE); 12345678910111213141516171819 12345678910111213141516171819 RxPermissions:权限管理核心类,该类通过传入 Activity 获取一个 Fragment 来进行权限申请回调处理,提供了一系列权限申请的方法,有多个权限单独处理回调和统一处理回调的方式,分别是 requestEach 和 request 方式。RxPermissionsFragment:权限申请回调处理 Fragment。该模块包含万能适配器和试图切换功能。适配器部分采用 ViewHolder 来管理数据的装载和展示,将数据与展示分离,提供了 DataHelper 接口来装载数据,ViewHelper 接口来处理 UI 的展示。其中的 HelperAdapter 提供了适配器的常用方法,基本能满足适配器的常用需求。 视图切换部分由 StatusLayoutManager 统一管理,通过传入相关配置进行视图展示处理。内部提供了 OnRetryListener 重试监听和 OnStatusViewListener 试图切换监听,并定义了一个自定义视图 StatusLayout 用来展示以下五种视图:
CONTENT:内容视图;LOADING:加载视图;EMPTY:空视图;NETWORK_ERROR:网络错误视图;OTHER_ERROR:其他错误视图。到此,XSnow 框架的所有模块就介绍完毕了,不知各位朋友是否对该框架有了更深入的了解。
以上描述有些部分可能讲解比较简单,这是因为有些模块本身不是很复杂,所以就没有做过多的讲解,如果想更清晰的了解该框架,最好的办法是直接 down 下源码观察,如果在看源码过程中有哪里不理解或觉得实现有问题而你有更好的方案都可以留言交流!
源码地址:https://github.com/xiaoyaoyou1212/XSnow,源码地址中提供了详细的使用文档,里面有版本介绍以及QQ群等信息,如果喜欢该框架不妨点点 star 并分享给身边的朋友,让更多的朋友参与进来,谢谢大家!