xUtils3是一个很好开发框架,它可以帮助我们在应用开发中简化很多工作,与老版本xUtils2.x相比API和结构有较大的重构,因此在使用前有必要详细学习它的使用。关于xUtils3的简介请看另一篇文章:xUtils3简介。
1 框架结构概览
在使用之前应该了解下它的主要类及接口关系,看下图:
下面我直接介绍它的详细使用吧。
2 在AndroidManifest.xml文件中配置xUtils3需要的权限
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
3 xUtils3初始化工作
// 在application的onCreate中初始化
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
x.Ext.init(this);
x.Ext.setDebug(true); // 是否输出debug日志
...
}
同时要在AndroidManifest.xml的application标签中添加如下代码:
android:name=”MyApplication”
这样初始化就完成了。
4 使用注解模块
view初始化,view绑定事件监听器等操作。注意看以下例子中@Event、@ViewInject、@ContentView的使用方法。
/**
* 1. 方法必须私有限定,
* 2. 方法参数形式必须和type对应的Listener接口一致.
* 3. 注解参数value支持数组: value={id1, id2, id3}
* 4. 其它参数说明见{@link org.xutils.event.annotation.Event}类的说明.
**/
@Event(value = R.id.btn_test_baidu1,
type = View.OnClickListener.class/*可选参数, 默认是View.OnClickListener.class*/)
private void onTestBaidu1Click(View view) {
...
}
例如:
public class DownloadItemViewHolder extends DownloadViewHolder {
@ViewInject(R.id.download_label)
TextView label;
@ViewInject(R.id.download_state)
TextView state;
@ViewInject(R.id.download_pb)
ProgressBar progressBar;
@ViewInject(R.id.download_stop_btn)
Button stopBtn;
public DownloadItemViewHolder(View view, DownloadInfo downloadInfo) {
super(view, downloadInfo);
refresh();
}
@Event(R.id.download_stop_btn)/*可选参数, 默认是View.OnClickListener.class*/
private void toggleEvent(View view) {
DownloadState state = downloadInfo.getState();
switch (state) {
case WAITING:
case STARTED:
downloadManager.stopDownload(downloadInfo);
break;
case ERROR:
case STOPPED:
case FINISHED:
Toast.makeText(x.app(), "已经下载完成", Toast.LENGTH_LONG).show();
break;
default:
break;
}
}
@Event(R.id.download_remove_btn)/*可选参数, 默认是View.OnClickListener.class*/
private void removeEvent(View view) {
try {
downloadManager.removeDownload(downloadInfo);
downloadListAdapter.notifyDataSetChanged();
} catch (DbException e) {
Toast.makeText(x.app(), "移除任务失败", Toast.LENGTH_LONG).show();
}
}
例如
@ContentView(R.layout.fragment_http)
public class HttpFragment extends BaseFragment {
/**
* 1. 方法必须私有限定,
* 2. 方法参数形式必须和type对应的Listener接口一致.
* 3. 注解参数value支持数组: value={id1, id2, id3}
* 4. 其它参数说明见{@link org.xutils.view.annotation.Event}类的说明.
**/
@Event(value = R.id.btn_test1,
type = View.OnClickListener.class/*可选参数, 默认是View.OnClickListener.class*/)
private void onTest1Click(View view) {
........
}
}
5 使用网络模块
5.1 上传多文件示例
@Event(value = R.id.btn_test2)
private void onTest2Click(View view) {
RequestParams params = new RequestParams("http://192.168.0.13:8080/upload");
// 加到url里的参数, http://xxxx/s?wd=xUtils
params.addQueryStringParameter("wd", "xUtils");
// 添加到请求body体的参数, 只有POST, PUT, PATCH, DELETE请求支持.
// params.addBodyParameter("wd", "xUtils");
// 使用multipart表单上传文件
params.setMultipart(true);
params.addBodyParameter(
"file",
new File("/sdcard/test.jpg"),
null); // 如果文件没有扩展名, 最好设置contentType参数.
try {
params.addBodyParameter(
"file2",
new FileInputStream(new File("/sdcard/test2.jpg")),
"image/jpeg",
// 测试中文文件名
"你+& \" 好.jpg"); // InputStream参数获取不到文件名, 最好设置, 除非服务端不关心这个参数.
} catch (FileNotFoundException ex) {
ex.printStackTrace();
}
x.http().post(params, new Callback.CommonCallback<String>() {
@Override
public void onSuccess(String result) {
Toast.makeText(x.app(), result, Toast.LENGTH_LONG).show();
}
@Override
public void onError(Throwable ex, boolean isOnCallback) {
Toast.makeText(x.app(), ex.getMessage(), Toast.LENGTH_LONG).show();
}
@Override
public void onCancelled(CancelledException cex) {
Toast.makeText(x.app(), "cancelled", Toast.LENGTH_LONG).show();
}
@Override
public void onFinished() {
}
});
5.2 加载网络图片数据到Listview的示例
private void loadImgList(String url) {
x.http().get(new RequestParams(url), new Callback.CommonCallback<String>() {
@Override
public void onSuccess(String result) {
imageListAdapter.addSrc(getImgSrcList(result));
imageListAdapter.notifyDataSetChanged();//通知listview更新数据
}
@Override
public void onError(Throwable ex, boolean isOnCallback) {
}
@Override
public void onCancelled(CancelledException cex) {
}
@Override
public void onFinished() {
}
});
}
}
6 使用image加载模块
6.1 加载图片的例子
加载网络图片到imageView中:
x.image().bind(image,”http://pic.baike.soso.com/p/20090711/20090711101754-314944703.jpg“);
也可先设置相关参数,再加载图片:
ImageOptions imageOptions =newImageOptions.Builder()
.setSize(DensityUtil.dip2px(120), DensityUtil.dip2px(120))//图片大小
.setRadius(DensityUtil.dip2px(5))//ImageView圆角半径
.setCrop(true)// 如果ImageView的大小不是定义为wrap_content, 不要crop.
.setImageScaleType(ImageView.ScaleType.CENTER_CROP)
.setLoadingDrawableId(R.mipmap.ic_launcher)//加载中默认显示图片
.setFailureDrawableId(R.mipmap.ic_launcher)//加载失败后默认显示图片
.build();
x.image().bind(image,"http://pic.baike.soso.com/p/20090711/20090711101754-314944703.jpg",imageOptions);
bind()方法的第二个参数换成本地图片地址,就可以加载本地存储的图片。
带有回调方法的加载图片:
// 设置加载图片的参数
ImageOptions options = new ImageOptions.Builder()
// 是否忽略GIF格式的图片
.setIgnoreGif(false)
// 图片缩放模式
.setImageScaleType(ScaleType.CENTER_CROP)
// 下载中显示的图片
.setLoadingDrawableId(R.drawable.ic_launcher)
// 下载失败显示的图片
.setFailureDrawableId(R.drawable.ic_launcher)
// 得到ImageOptions对象
.build();
// 加载图片
x.image().bind(imgv, imagUrl, options, new CommonCallback<Drawable>() {
@Override
public void onSuccess(Drawable arg0) {
LogUtil.e("下载成功");
}
@Override
public void onFinished() {
LogUtil.e("下载完成");
}
@Override
public void onError(Throwable arg0, boolean arg1) {
LogUtil.e("下载出错," + arg0.getMessage());
}
@Override
public void onCancelled(CancelledException arg0) {
LogUtil.e("下载取消");
}
});
// 加载本地图片
// x.image().bind(imgv, "assets://test.gif", options);
// x.image().bind(iv_big_img, new
// File("/sdcard/test.gif").toURI().toString(), imageOptions);
// x.image().bind(iv_big_img, "/sdcard/test.gif", imageOptions);
// x.image().bind(iv_big_img, "file:///sdcard/test.gif", imageOptions);
// x.image().bind(iv_big_img, "file:/sdcard/test.gif", imageOptions);
7 使用数据库操纵模块
这部分,我们先分析下相关的源码接口,后面再给出一个使用的范例。
DbManager部分源码如下:
/**
* 数据库访问接口
*/
public interface DbManager extends Closeable {
DaoConfig getDaoConfig();
SQLiteDatabase getDatabase();
/**
* 保存实体类或实体类的List到数据库,
* 如果该类型的id是自动生成的, 则保存完后会给id赋值.
*
* @param entity
* @return
* @throws DbException
*/
<pre name="code" class="java"> boolean saveBindingId(Object entity) throws DbException;
/**
* 保存或更新实体类或实体类的List到数据库, 根据id对应的数据是否存在.
*
* @param entity
* @throws DbException
*/
void saveOrUpdate(Object entity) throws DbException;
/**
* 保存实体类或实体类的List到数据库
*
* @param entity
* @throws DbException
*/
void save(Object entity) throws DbException;
/**
* 保存或更新实体类或实体类的List到数据库, 根据id和其他唯一索引判断数据是否存在.
*
* @param entity
* @throws DbException
*/
void replace(Object entity) throws DbException;
/ delete
void deleteById(Class<?> entityType, Object idValue) throws DbException;
void delete(Object entity) throws DbException;
void delete(Class<?> entityType) throws DbException;
int delete(Class<?> entityType, WhereBuilder whereBuilder) throws DbException;
/ update
void update(Object entity, String... updateColumnNames) throws DbException;
int update(Class<?> entityType, WhereBuilder whereBuilder, KeyValue... nameValuePairs) throws DbException;
/ find
<T> T findById(Class<T> entityType, Object idValue) throws DbException;
<T> T findFirst(Class<T> entityType) throws DbException;
<T> List<T> findAll(Class<T> entityType) throws DbException;
<T> Selector<T> selector(Class<T> entityType) throws DbException;
DbModel findDbModelFirst(SqlInfo sqlInfo) throws DbException;
List<DbModel> findDbModelAll(SqlInfo sqlInfo) throws DbException;
/ table
/**
* 获取表信息
*
* @param entityType
* @param <T>
* @return
* @throws DbException
*/
<T> TableEntity<T> getTable(Class<T> entityType) throws DbException;
/**
* 删除表
*
* @param entityType
* @throws DbException
*/
void dropTable(Class<?> entityType) throws DbException;
/**
* 添加一列,
* 新的entityType中必须定义了这个列的属性.
*
* @param entityType
* @param column
* @throws DbException
*/
void addColumn(Class<?> entityType, String column) throws DbException;
/ db
/**
* 删除库
*
* @throws DbException
*/
void dropDb() throws DbException;
/**
* 关闭数据库,
* xUtils对同一个库的链接是单实例的, 一般不需要关闭它.
*
* @throws IOException
*/
void close() throws IOException;
/ custom
int executeUpdateDelete(SqlInfo sqlInfo) throws DbException;
int executeUpdateDelete(String sql) throws DbException;
void execNonQuery(SqlInfo sqlInfo) throws DbException;
void execNonQuery(String sql) throws DbException;
Cursor execQuery(SqlInfo sqlInfo) throws DbException;
Cursor execQuery(String sql) throws DbException;
........
}
通过DbManager这个类我们知道主要它做了以下几件事情:
7.1 getDaoConfig 获取数据库的配置信息
DaoConfig getDaoConfig();
7.2 getDatabase 获取数据库实例
SQLiteDatabase getDatabase();
7.3 saveBindingId saveOrUpdate save 插入数据的3个方法(保存数据)
/**
* 保存实体类或实体类的List到数据库,
* 如果该类型的id是自动生成的, 则保存完后会给id赋值.
*
* @param entity
* @return
* @throws DbException
*/
boolean saveBindingId(Object entity) throws DbException;
/**
* 保存或更新实体类或实体类的List到数据库, 根据id对应的数据是否存在.
*
* @param entity
* @throws DbException
*/
void saveOrUpdate(Object entity) throws DbException;
/**
* 保存实体类或实体类的List到数据库
*
* @param entity
* @throws DbException
*/
void save(Object entity) throws DbException;
save和saveOrUpdate的区别就是当一个实体里面的主键一样时如果使用saveOrUpdate会将当前主键对应的这条数据进行替换,而如果你使用了save就会报错。
saveBindingId主要是存进去的数据如果当前表有主键回合主键进行绑定关联。
7.4 replace 只有存在唯一索引时才有用 慎重
/**
* 保存或更新实体类或实体类的List到数据库, 根据id和其他唯一索引判断数据是否存在.
*
* @param entity
* @throws DbException
*/
void replace(Object entity) throws DbException;
7.5 delete操作的4种方法(删除数据)
///////////// delete
void deleteById(Class<?> entityType, Object idValue) throws DbException;
void delete(Object entity) throws DbException;
void delete(Class<?> entityType) throws DbException;
int delete(Class<?> entityType, WhereBuilder whereBuilder) throws DbException;
7.6 update操作的2种方法(修改数据)
///////////// update
void update(Object entity, String... updateColumnNames) throws DbException;
int update(Class<?> entityType, WhereBuilder whereBuilder, KeyValue... nameValuePairs) throws DbException;
7.7 find操作6种方法(查询数据)
/ find
<T> T findById(Class<T> entityType, Object idValue) throws DbException;
<T> T findFirst(Class<T> entityType) throws DbException;
<T> List<T> findAll(Class<T> entityType) throws DbException;
<T> Selector<T> selector(Class<T> entityType) throws DbException;
DbModel findDbModelFirst(SqlInfo sqlInfo) throws DbException;
List<DbModel> findDbModelAll(SqlInfo sqlInfo) throws DbException;
六中查询方法的使用举例:
当前数据库中的表的效果如下:
1.findById的使用
该方法主要是通过主键的值来进行查找表里面的数据
需求:查找上方person表里面id为3的数据
private void query(){
try {
PersonTable person = db.findById(PersonTable.class, "2");
Log.e("person",person.toString());
} catch (DbException e) {
e.printStackTrace();
}
}
结果如下:
2.findFirst的使用
该方法主要是返回当前表里面的第一条数据
需求:查找上方person表里面的第一条数据
private void query() {
try {
PersonTable person = db.findFirst(PersonTable.class);
Log.e("person", person.toString());
} catch (DbException e) {
e.printStackTrace();
}
}
3.findAll的使用
该方法主要是返回当前表里面的所有数据
需求:查找person表里面的所有数据
private void query() {
try {
List<PersonTable> persons = db.findAll(PersonTable.class);
Log.e("persons", persons.toString());
} catch (DbException e) {
e.printStackTrace();
}
}
4.selector的使用
该方法主要是用来进行一些特定条件的查找
需求:查找person表里面age大于30并且性别为man的数据
private void query() {
try {
List<PersonTable> persons = db.selector(PersonTable.class).where("age", ">", 30).and("sex", "=", "man").findAll();
for(PersonTable person:persons){
Log.e("person",person.toString());
}
} catch (DbException e) {
e.printStackTrace();
}
}
5.findDbModelFirst的使用
说起这个方法,该方法返回一个DbModel对象,那么该对象是什么呢?
DbModel源码如下:
public final class DbModel {
/**
* key: columnName
* value: valueStr
*/
private HashMap<String, String> dataMap = new HashMap<String, String>();
public String getString(String columnName) {
return dataMap.get(columnName);
}
public int getInt(String columnName) {
return Integer.valueOf(dataMap.get(columnName));
}
public boolean getBoolean(String columnName) {
String value = dataMap.get(columnName);
if (value != null) {
return value.length() == 1 ? "1".equals(value) : Boolean.valueOf(value);
}
return false;
}
public double getDouble(String columnName) {
return Double.valueOf(dataMap.get(columnName));
}
public float getFloat(String columnName) {
return Float.valueOf(dataMap.get(columnName));
}
public long getLong(String columnName) {
return Long.valueOf(dataMap.get(columnName));
}
public Date getDate(String columnName) {
long date = Long.valueOf(dataMap.get(columnName));
return new Date(date);
}
public java.sql.Date getSqlDate(String columnName) {
long date = Long.valueOf(dataMap.get(columnName));
return new java.sql.Date(date);
}
public void add(String columnName, String valueStr) {
dataMap.put(columnName, valueStr);
}
/**
* @return key: columnName
*/
public HashMap<String, String> getDataMap() {
return dataMap;
}
/**
* @param columnName
* @return
*/
public boolean isEmpty(String columnName) {
return TextUtils.isEmpty(dataMap.get(columnName));
}
}
通过源码,我们分析发现DbModel本质就是一个key为当前表的字段,value为当前某条记录的值的一个HashMap.
需求:查找person表中第一条数据的那个人的年龄age是多少。
private void query() {
try {
DbModel model = db.findDbModelFirst(new SqlInfo("select * from person"));
Log.e("age", model.getString("age"));
} catch (DbException e) {
e.printStackTrace();
}
}
注意上面的sqlInfo对象的创建的构造参数只需要传入一个sql语句即可。
6.findDbModelAll的用法
该方法的用途就是返回满足sqlInfo信息的所有数据的字段的一个集合。
需求:查找person表中年龄age大于25里面的所有人的姓名
[java] view plain copy print?在CODE上查看代码片派生到我的代码片
private void query() {
try {
List<DbModel> persons = db.findDbModelAll(new SqlInfo("select * from person where age > 25"));
for(DbModel person:persons){
Log.e("name", person.getString("name"));
}
} catch (DbException e) {
e.printStackTrace();
}
}
基本把查询的6种方式都说了一遍,当然上面的6种需求不一定完全用上面的查询方法可以查出结果,我这么查询的目的主要是带领大家熟悉一下XUtils3的6种查询方法是如何使用的,会了上面的6种方法,我相信你的查询不会有太大问题,至于复杂的查询无非就是sql语句的基本功力了。
7.8 dropTable 删除表
/**
* 删除表
*
* @param entityType
* @throws DbException
*/
void dropTable(Class<?> entityType) throws DbException;
7.9 addColumn 添加一列
/**
* 添加一列,
* 新的entityType中必须定义了这个列的属性.
*
* @param entityType
* @param column
* @throws DbException
*/
void addColumn(Class<?> entityType, String column) throws DbException;
7.10 dropDb 删除数据库
/**
* 删除库
***重点内容**
* @throws DbException
*/
void dropDb() throws DbException;
7.11 数据库操作模块使用的DEMO
先建一个类,用来生成数据库中的表,这里新建一个StudentInfo类(注意里面的@标签的使用,使用这些标签生成表的结构信息)内容如下:
@Table(name = "info")
public class StudentInfo {
@Column(name = "id", isId = true)
private int id;
@Column(name = "name")
private String name;
@Column(name = "age")
private int age;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
然后看如何使用:
DbManager.DaoConfig daoConfig = new DaoConfig()
// 数据库的名字
.setDbName("SudentInfo")
// 保存到指定路径
// .setDbDir(new
// File(Environment.getExternalStorageDirectory().getAbsolutePath()))
// 数据库的版本号
.setDbVersion(1)
// 数据库版本更新监听
.setDbUpgradeListener(new DbUpgradeListener() {
@Override
public void onUpgrade(DbManager arg0, int arg1, int arg2) {
LogUtil.e("数据库版本更新了!");
}
});
DbManager manager = x.getDb(daoConfig);
try {
//创建对象,用来生成表
StudentInfo info = new StudentInfo();
info.setAge(16);
info.setName("小花");
//创建表
manager.saveOrUpdate(info);
} catch (DbException e) {
e.printStackTrace();
}
8 使用task管理模块
此模块使用比较简单,主要是使用任务管理接口TaskController提供的方法,大大简化了对任务的操作。
下图是TaskController接口方法列表:
TaskController接口的详细定义如下:
public interface TaskController {
/**
* 在UI线程执行runnable.
* 如果已在UI线程, 则直接执行.
*
* @param runnable
*/
void autoPost(Runnable runnable);
/**
* 在UI线程执行runnable.
* post到msg queue.
*
* @param runnable
*/
void post(Runnable runnable);
/**
* 在UI线程执行runnable.
*
* @param runnable
* @param delayMillis 延迟时间(单位毫秒)
*/
void postDelayed(Runnable runnable, long delayMillis);
/**
* 在后台线程执行runnable
*
* @param runnable
*/
void run(Runnable runnable);
/**
* 移除post或postDelayed提交的, 未执行的runnable
*
* @param runnable
*/
void removeCallbacks(Runnable runnable);
/**
* 开始一个异步任务
*
* @param task
* @param <T>
* @return
*/
<T> AbsTask<T> start(AbsTask<T> task);
/**
* 同步执行一个任务
*
* @param task
* @param <T>
* @return
* @throws Throwable
*/
<T> T startSync(AbsTask<T> task) throws Throwable;
/**
* 批量执行异步任务
*
* @param groupCallback
* @param tasks
* @param <T>
* @return
*/
<T extends AbsTask<?>> Callback.Cancelable startTasks(Callback.GroupCallback<T> groupCallback, T... tasks);
}
9、文档参考
9.2 http://blog.csdn.net/a1002450926/article/details/50364196