本文为菜鸟窝作者刘婷的连载。”商城项目实战”系列来聊聊仿”京东淘宝的购物商城”如何实现。
刚开始的时候,在 GitHub 上面出现了一款强大的开源框架叫 xUtils,里面包含了很多实用的android工具,并且支持大文件上传,更全面的 http 请求协议支持(10种谓词),拥有更加灵活的 ORM,更多的事件注解支持且不受混淆影响,该框架最低兼容版本为 android 2.2 (api level 8)。但是随着 Android 版本的不断更新,特别是 Android 6.0 之后,xUtils 的兼容不是很好,因此就出现了升级版的 xUtils,也就是 xUtils3。
xUtils3 详细介绍
xUtils3 是 xUtils 的升级版本,包含了orm, http(s), image, view注解, 但依然很轻量级(246K), 最主要是特性强大, 方便扩展,当然对比之前的 xUtils,在 xUtils3 中很多的 API 接口都已经改变了,使用方法也和之前不同了,所以本文主要是讲解最新的 xUtils3 的详细介绍以及该框架下的 ViewUtils 模块的最新用法。
1. xUtils3 的特性
1.1 xUtils3 的主要特性
xUtils3 的主要特性如下。
- 稳定的基石: AbsTask 和统一的回调接口 Callback, 任何异常, 即使你的回调方法实现有异常都会进入 onError,任何情况下 onFinished 总会让你知道任务结束了。
- 基于高效稳定的 orm 工具,http 模块得以更方便的实现 cookie (支持 domain、 path、 expiry 等特性)和 缓存(支持 Cache-Control、Last-Modified、 ETag 等特性)的支持。
- 有了强大的 http 及其下载缓存的支持,image 模块的实现相当的简洁,并且支持回收被 view 持有,但被 Mem Cache 移除的图片,减少页面回退时的闪烁。
- View 注解模块仅仅400多行代码却灵活的支持了各种 View 注入和事件绑定, 包括拥有多了方法的 listener 的支持。
1.2 其他特性
xUtils3 的一些其他特性。
- 支持超大文件(超过 2G )上传。
- 更全面的 http 请求协议支持(11种谓词),在 xUtils 中只支持10种谓词。
- 拥有更加灵活的 ORM, 和 greenDao 一致的性能。
- 更多的事件注解支持且不受混淆影响。
- 图片绑定支持 gif (受系统兼容性影响, 部分 gif 文件只能静态显示)、webp,支持圆角,圆形, 方形等裁剪,支持自动旋转。
- 从 3.5.0 开始不再包含 libwebpbackport.so,需要在 Android4.2 以下设备兼容 webp 的请使用 3.4.0 版本。
2. xUtils3 主要四大模块
xUtils 中目前包括了主要的四大模块,分别为 DbUtils 模块、ViewUtils 模块、HttpUtils 模块以及 BitmapUtils 模块,下面对这四大模块进行介绍。
2.1 DbUtils 模块
- Android 中的 orm 框架,一行代码就可以进行增删改查。
- 支持事务,默认关闭。
- 可通过注解自定义表名,列名,外键,唯一性约束,NOT NULL约束,CHECK 约束等(需要混淆的时候请注解表名和列名)。
- 支持绑定外键,保存实体时外键关联实体自动保存或更新。
- 自动加载外键关联实体,支持延时加载。
- 支持链式表达查询,更直观的查询语义。
2.2 ViewUtils 模块
- android 中的 ioc 框架,完全注解方式就可以进行 UI,资源和事件绑定。
- 新的事件绑定方式,使用混淆工具混淆后仍可正常工作。
- 目前支持常用的20种事件绑定,比如 setClickListener 等。
2.3 HttpUtils 模块
- 支持同步,异步方式的请求。
- 支持大文件上传,上传大文件不会出现 oom 内存溢出情况。
- 支持 GET,POST,PUT,MOVE,COPY,DELETE,HEAD,OPTIONS,TRACE,CONNECT 的请求。
- 下载支持301/302重定向,支持设置是否根据 Content-Disposition 重命名下载的文件。
- 返回文本内容的请求(默认只启用了 GET 请求)支持缓存,可设置默认过期时间和针对当前请求的过期时间。
2.4 BitmapUtils 模块
- 加载 Bitmap 的时候无需考虑 Bitmap 加载过程中出现的 oom 和 android 容器快速滑动时候出现的图片错位等现象。
- 支持加载网络图片和本地图片。
- 内存管理使用 lru 算法,更好的管理 Bitmap 内存。
- 可配置线程加载线程数量,缓存大小,缓存路径,加载显示动画等。
xUtils3 中 ViewUtils 的主要作用
ViewUtils 的主要作用有两点,一是可以完全注解方式就可以进行 UI 绑定和事件绑定,另外一个就是无需 findViewById 和 setOnClickListener 等。而其中的 UI 绑定和事件绑定下面详细介绍。
1. UI 绑定
UI 绑定简而言之就是针对于控件和 View 了,分为多种绑定方法。
@ContentView(R.layout.view_acti); //setContentView 注解在activity的声明上方
@ViewInject(R.id.lv_test); //反射view 注解在一个view声明上
2. 事件绑定
事件绑定就是指监听事件的注解,比如 setOnClickListener 等。
@Event(R.id.button) //将一个自定义的方法绑定到一个 view 的事件上
至于具体的使用方法就在下面了。
xUtils3 中 ViewUtils 的使用方法
xUtils3 框架中包含了很多的工具,主要的四大模块功能也很强大,这次主要是要讲解其中的 ViewUtils 模块的使用。
1. Gradle 添加依赖
在 module 下的 build.gradle 文件下面添加对 xUtils3 的依赖。
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.2.0'
compile 'com.android.support.constraint:constraint-layout:1.0.1'
testCompile 'junit:junit:4.12'
compile 'org.xutils:xutils:3.5.0'
}
2. ViewUtils 初始化
在 Activity 和 Fragment 中初始化 ViewUtils 模块略有不同,所以就分开介绍了。
2.1 Activity 中初始化
在 Activity 中初始化比较简单,直接在 onCreate 中一行代码就搞定了。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
x.view().inject(this);
}
2.2 Fragment 中初始化
Fragment 的生命周期依赖于 Activity,另外在 Fragment 中一些方法也与 Activity 不同,所以 ViewUtils 的初始化方法也不太一样了。
private boolean injected = false;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
injected = true;
return x.view().inject(this, inflater, container);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
if (!injected) {
x.view().inject(this, this.getView());
}
}
其中 injected 是用来标识是否已经注入了 View ,如果还没有注入,在 onViewCreated 中要写入注入 View 的方法。
3. ViewUtils 绑定控件
一般在 Activity 或者 Fragment 中声明控件,都要使用方法 findViewById,如果控件一旦多了,就会很麻烦,代码要写不少,但是使用 ViewUtils 可以通过注解的方式直接进行 UI 绑定,方法也很简单。
@ViewInject(R.id.textView)
private TextView textView;
4. ViewUtils 绑定布局
在为 Activity 或者 Fragment 添加布局时,我们都会使用到 setContentView(int layoutRes) 方法,在 ViewUtils 添加了直接注解布局的方法,如下。
@ContentView(R.layout.activity_main)
public class MainActivity extends AppCompatActivity {
.....
}
在 Fragment 中注解方法是一样的,在 Fragment 中直接添加就好。
5. ViewUtils 绑定事件
在之前的按钮的点击事件、列表选项的 item 点击事件等,写起来代码都比较多些,而使用 ViewUtils 都可以变得简单起来,先来看下按钮的点击事件的绑定。
// 取消了之前使用方法名绑定事件的方式,使用id绑定不受混淆影响
// 支持绑定多个id @Event({R.id.id1, R.id.id2, R.id.id3})
// or @Event(value={R.id.id1, R.id.id2, R.id.id3}, parentId={R.id.pid1, R.id.pid2, R.id.pid3})
// 更多事件支持参见ViewCommonEventListener类和包com.lidroid.xutils.view.annotation.event。
@Event(R.id.test_button)
public void testButtonClick(View v) { // 方法签名必须和接口中的要求一致
...
}
上面是按钮的点击事件的绑定,很方便,再来看看列表选项的 item 点击事件的绑定。
//选项的点击事件 OnItemClickListener
@Event(value = R.id.lv_img, type = AdapterView.OnItemClickListener.class)
private void onImageItemClick(AdapterView<?> parent, View view, int position, long id) {
....
}
ViewUtils 所支持的事件的绑定还有很多种,这里就主要介绍上面两种,更多的使用方法请参考 xUtils3 源码。
结束语
xUtils3 在 xUtils 的基础上优化了不少,ViewUtils 注解也更为的简单明了,有了 ViewUtils,我们就不用像之前一样不断的对控件进行声明,另外对于事件的处理也简化了不少,在后期的商城项目实战中,都将使用 ViewUtils 来做 UI 的绑定以及事件的绑定。