模块化是一种成熟的业务解耦思想,目前已普遍应用在APP的开发中。以前写过一篇文章——Android模块化实践对APP模块化的过程及遇到的问题进行了介绍。具体的实例代码最近也完善的差很少了,因此写篇文章介绍一下这个项目——SimpleProject, 一个以分层思想+模块化开发的通用框架,将会被长期维护。java
本项目是按照Android模块化实践中介绍的结构来开展的,因此可先看下这篇文章了解一下基本结构。项目结构以下所示:git
其中,MainModule, BaseComponentDemo, BaseLibraryDemo和CommonBusinessDemo都是业务层模块,他们的关系如图所示:github
MainModule是整个APP的主模块,用来实现APP中主页和路由跳转相关的逻辑,同时也做为Application与其余模块关联的枢纽。数据库
BaseComponentDemo, BaseLibraryDemo和CommonBusinessDemo是子业务模块,都依赖于library目录中的三个公共模块。这三个模块一方面是用来展现业务模块化实现过程,另外一方面也是library中三个模块的示例代码。因此这三个模块中没有什么核心的代码,下面主要介绍一下library中的三个模块。api
默认状况下,建立的Module都是在Project目录下,可是当模块比较的多的时候,定位代码时仍是比较繁琐的,因此推荐将底层的Module放在建立的library目录中,而后在setting.gradle中对Module的路径进行配置:数组
project(':baselibrary').projectDir = new File('library/baselibrary')
project(':basecomponent').projectDir = new File('library/basecomponent')
project(':commonbusiness').projectDir = new File('library/commonbusiness')
复制代码
有时候也会引入一些第三方的Module, 此时也可将其放在library目录中,或者建立其余的目录用来存放第三方的Module,而后在setting.gradle中进行配置。这样Project目录下只有业务层的Module,项目结构看起来会清晰不少。缓存
baselibrary是Common组件层的实现,包括各类经常使用的工具类,通用的UI库,数据源的封装(包括网络,文件,数据库)。微信
commonutils中包含了丰富的工具类,具体介绍以下:网络
AppUtil: App相关的一些操做,如版本号,进程号,是否已安装,是否正在运行,是否运行在前台等;
BitmapUtil: Bitmap相关的一些操做,如缩放,与Drawable之间的转换等;
CollectionUtil: 与集合/数组相关的操做;
ConvertUtil: 基本类型与String之间的转换操做;
DateTimeUtil: 时间格式化相关的操做;
DeviceUtil: 设备相关的操做,如获取系统的各类参数;
EncryptUtil: 加密操做,如MD5, 隐藏手机号,邮箱等操做;
FileUtil: 与文件相关的操做;
InputMethodUtil: 与键盘相关的操做,如打开/隐藏键盘,键盘弹出时调整EditText位置等;
LaunchUtil: 跳转到其余APP的操做,如打开电话,短信等;
LogUtil: 日志工具类;
NetworkUtil: 与网络相关的工具类,如获取网络参数,获取联网状态等;
PermissionUtil: 权限验证类;
RomUtil: 判断手机ROM的类型;
ScrollStateUtil: 判断可滑动View是否到达顶部或底部;
SpannableStringUtil: 富文本工具类;
ToastUtil: Toast工具类
VerificationUtil: 验证工具类,如手机号,邮箱,身份证,是否为中文等;
ViewBgUtil: 动态设置View背景的工具类;
ShadowDrawable: 被View设置阴影的工具类;
复制代码
Android中经常使用的数据源也就四个:SharePreference,文件,数据库和网络。app
SharePreference是Android提供的一种以key-value结构用来存储少许数据的方式,本质上也是文件的存储方式,可是直接使用时比较繁琐,为了简化调用过程,项目中提供了它的封装版——PreferencesManager,支持同步和异步两种方式。
文件方式就是简单的文件读写,这里的文件缓存使用了ACache。
与文件同样,数据库也算是Android中的低频数据源,直接使用GreenDAO便可。
网络是Android开发中主要的数据源,会被大量使用,因此须要进行简单的封装,从而简化网络请求的过程。网络框架使用了Retrofit。 http目录中是整个网络框架的封装,其中提供了公共参数,缓存,Cookie,认证四种拦截器。同时提供了Gson数据转换的兼容类,避免异常数据转换时因类型不匹配而致使的闪退。
网络请求示例代码:
HttpManager.getInstance().executeRequest(apiService.getUserInfo(), new ResponseProcessor.RequestListener<UserInfoBean>() {
@Override
public void onSuccess(UserInfoBean response) {
// 请求成功
}
@Override
public void onFailure(int code, String msg) {
// 请求失败
}
});
复制代码
通用UI是一些自定义View,放在这个位置的自定义View须要有高度的可定制性和与业务无关的特征。
CircleProgressBar: 圆形进度条;
LevelView: 相似Uber的等级选择器;
RefreshLayout: 下拉刷新、上拉加载组件;
ResilienceListView: 下拉可回弹的ListView;
ShapeImageView: 可定义形状的ImageView;
TabLayout: 相似微信底部的Tab组件;
复制代码
basecomponent是基础业务层的实现,用于统一APP的代码结构和UI风格。主要包括Activity&Fragment,Dialog的封装。
Activity&Fragment做为Android中承载View的组件,它们的风格基本决定了APP的总体风格。其实就目前主流的设计,Activity/Fragment的UI也就几种状态:
总的来讲也就这4种状况的组合。针对这4种状况提供了如下封装类:
而对于NavigationBar也提供了三种样式: 白底,透明,半透明,根据须要进行设置便可。
Dialog也是Android开发中经常使用的UI组件,这里提供了普通对话框,单选对话框,多选对话框,底部对话框四种方式,同时对每一种提供了自定义样式和Material样式两种风格,具体可参考Android通用UI组件之Dialog
commonbusiness是公共组件层的实现。其中包括APP中一些通用的功能,如登陆验证,权限验证,第三方登陆,分享,支付,推送等功能。
在Android开发中,有一些页面是须要登陆才能查看的,若是直接使用判断登陆状态的方式,就是显得很繁琐。所谓为了简化这种验证过程,项目中提供了基于AOP的方式,开发者中须要验证登陆状态的方法上面使用@CheckLogin注解便可。具体代码参考aspect目录。
Android6.0以后权限的获取都是经过动态获取的,可是获取的过程比较繁琐,因此为了简化权限的获取过程,这里也使用了基于AOP的权限申请。在须要申请权限时,使用@CheckPermission注解便可,代码以下所示:
@CheckPermission(permissions = {Manifest.permission.CAMERA,}, permissionDesc = "没有权限没法使用相机", settingDesc = "快去设置中开启权限")
private void setUserIcon() {
}
复制代码
当用户拒绝了权限申请后,弹出toast提示permissionDesc中的内容,当勾选了【再也不询问】拒绝后,再次申请就会弹出Dialog, 提示内容为settingDesc,固然,这两个字段也是有默认值的,若是不须要详细的提示,可不用设置。
如今的应用除了内置的登陆功能外,为了便于用户使用,一般还会提供第三方登陆的功能。一般使用的第三方登陆也就微信,微博,QQ三种。这里为第三方登陆提供了统一的接口,须要登陆时直接调用便可。
目前APP的主要分享渠道是微信,微博和QQ,因此分享模块也只集成了这三种分享方式。使用时只须要在相应的开发平台上建立应用并配置参数,而后在分享模块中配置参数便可。固然,项目中也提供了一个分享页面——ShareActivity,分享时调用ShareActivity.enter(...)方法便可。
项目中集成了微信支付和支付宝支付,而且为支付提供了统一了接口,使用时只须要将从后台获取的参数传入便可
// requestStr是后台返回的订单相关的参数
PayManager.getInstance(PayActivity.this).payByAliPay(this, requestStr, new PayManager.AliPayListener() {
@Override
public void onSuccess() {
ToastUtil.show("支付成功");
}
@Override
public void onFailure(Exception e) {
ToastUtil.show("支付失败" + e.getMessage());
}
});
复制代码
// 根据后台返回的微信支付的参数构造PayRequestBean对象
PayRequestBean payRequest = new PayRequestBean(...)
PayManager.getInstance(PayActivity.this).payByWeChat(payRequest, new PayManager.AliPayListener() {
@Override
public void onSuccess() {
ToastUtil.show("支付成功");
}
@Override
public void onFailure(Exception e) {
ToastUtil.show("支付失败" + e.getMessage());
}
});
复制代码
目前推送的推送率基本都是经过第三方推送SDK组合的方式来保障的,项目中集成了小米,华为,极光推送三种方式,根据机型动态设置推送方式,小米手机使用小米推送,华为推送使用华为推送,其余的品牌则使用极光推送。开发时只须要在Applicataion中调用PushManager的init方法进行初始化,而且设置推送的监听便可。
PushManager.getInstance().initPush(getApplicationContext(), "小米推送的appId",
"小米推送的appKey");
PushManager.getInstance().setPushListener(new PushListener() {
@Override
public void onReceiveMessage(Context context, int pushChannel, Object object) {
/**
* 接收到自定义消息时的回调
*/
}
@Override
public void onReceiveNotification(Context context, int pushChannel, Object object) {
/**
* 接收到通知时的回调
*/
}
@Override
public void onNotificationClicked(Context context, int pushChannel, Object object) {
/**
* 点击推送通知时的回调
*/
}
});
复制代码
目前的项目已经有个大概的轮廓了,可是细节方面还有许多须要完善的,同时实例代码的展现也还不够详细,随后会进一步完善,感兴趣的小伙伴可关注一下。