弓背霞明剑照霜,秋风走马出咸阳。这篇文章主要讲述一种Android分包策略推荐相关的知识,希望能为你提供帮助。
分包的重要性
在架构一个App时,大家往往都在关注新潮的技术,却忽略了一点,那就是分包。很多人可能没有一套分包的原则,凭感觉甚至随心所欲地创建package或将代码放到任意的package中。
虽然最终不会影响App功能,但这个问题其实非常严重。一种不好的分包策略带来的影响将会一直持续在App的开发迭代周期中,主要表现为以下几点:
- 代码混乱,功能模块界限模糊
- 不易阅读与维护,尤其对新人来说
- 功能扩展与重用困难
- 包间耦合比较高
一种分包策略
反例分析先来看一个“反例”(已加引号,如此分包者轻拍)。曾见过一些第三方项目或开源项目,它们的分包策略是这样的:
- 把应用中所有的Activity放到一个包中,如com.example.activities
- 把应用中所有的Fragment放到另一个包中,如com.example.fragments
- ……
优点呢?或许说分类特别清晰,如所有的Activity都在一起,但是仔细想想,这样又有什么意义呢?
缺点却非常明显:
- 当看到这样的一个App分包结构时,大家可能都不知道该App有哪些功能、应用入口在哪里
- 代码混乱,杂糅在一起,没有清晰的模块界限
- 可读性差,查找一个功能页面时,可能需要跨多个包才能找到
- 修改维护则更加麻烦,根本不知道某个类是否在其他包中使用
- ……
先抛出个人推荐的分包原则:按功能模块分包。
这样说有点抽象,我们细化到一个App示例中去,假设一个App具有如下功能:
基础支持功能
- 网络请求
- 图片处理
- 数据库
- ……
- 新闻相关功能模块
- 电影相关功能模块
- 音乐相关功能模块
- ……
- 将网络功能相关代码归到一个包,如com.example.network,至于具体用OkHttp还是Volley或者自己封装HttpURLConnection都无所谓。
- 将图片加载、缩放、缓存等相关功能代码归到一个包,如com.example.image,同样跟使用哪种图片框架无关。
- 将Sqlite数据库相关操作的代码归到一个包,如com.example.db。
- 将新闻功能模块的相关业务代码归到一个包,如com.example.news,同时新闻功能相关的所有Activity和Fragment都放到这个包中。
- 将电影功能模块的相关业务代码归到一个包,如com.example.movie,同时电影功能相关的所有Activity和Fragment都放到这个包中。
- 将音乐功能模块的相关业务代码归到一个包,如com.example.music,同时音乐功能相关的所有Activity和Fragment都放到这个包中。
- 对于adapter,如是封装的通用的adapter,则可归到com.example.adapter中,如仅仅是某个Activity自己用的adapter,也可放到业务模块的包中,这里推荐所有adapter放到一个独立的包中,因为我们查找代码时,往往从功能模块角度入口,根据功能分包原则,可以快速找到对应包中的Activity,找到了Activity,其用到的adapter、entity便也可以迅速找到,因此不必也放到功能模块的包中。
- 对于自定义控件,可以统一归到一个包,如com.example.widget。
- 对于某些基类,如BaseActivity和BaseFragment等可以放到一个叫com.example.base的包中。
- 对于数据对象实体,可统一放到com.example.entity中,不要放到具体功能模块的包中,原因第7点已提及,另外实体还可能重用、继承等。
- 对于业务无关的公用方法和工具类,可以放到com.example.util中。
- ……
java
|--- com
|---example
|--- base
||--- BaseActivity.java
||--- BaseFragment.java
||--- xxx.java
|
|--- network
||--- HttpClient.java
||--- xxx.java
|
|--- image
||--- ImageManager.java
||--- xxx.java
|
|--- db
||--- DbManager.java
||--- xxx.java
|
|--- news
||--- NewsActivity.java
||--- NewsFragment.java
||--- xxx.java
|
|--- movie
||--- MovieActivity.java
||--- MovieFragment.java
||--- xxx.java
|
|--- music
||--- MusicActivity.java
||--- MusicFragment.java
||--- xxx.java
|
|--- entity
||--- Movie.java
||--- News.java
||--- xxx.java
|
|--- adapter
||--- AbsAdapter.java
||--- MovieAdapter.java
|
|--- widget
||--- CircleImageView.java
||--- xxx.java
|
|--- util
|--- ToastUtil.java
|--- xxx.java
- 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
- 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
- 从分包结构就能大概了解该App的功能
- 高度模块化,可读性及可维护性大大提升
- 功能模块导航清晰,很容易查找相关功能代码,哪怕是新人也能快速找到对应代码
- 包与包之间的耦合性降低,添加或删除功能模块变得简单
- 修改代码时,一般仅涉及某个功能,一般不用担心影响到其他包中的功能实现
- 更加抽象化、模块化,方便扩展和重用,尤其是基础功能模块
- 从代码访问权限角度来看,包内调用权限可替代包间调用,安全性也会提高
分包本身就是一个开放性的问题,没有固定或最优的方案,上面推荐的策略也只是一些基本原则,具体细节可根据App实际情况制定,欢迎探讨。
推荐阅读
- Android中锁屏密码算法解析以及破解方案
- android 代码实现模拟用户点击滑动等操作
- Android内存重启之静态变量被回收导致nullPoint问题
- 身份证识别,手机银行APP必备插件
- Android性能优化(ViewStub)
- Citrix XenApp/XenDesktop版本正确选择
- 关于android SDK安装Failed to fetch URL http://dl-ssl.google.com/android/repository/addons_list-1.xml出错二(
- 安卓权威编程-笔记(19章 使用SoundPool播放音频)
- JCameraView 仿微信拍照Android控件(点击拍照,长按录小视频)