开源库xUtils3使用详解

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.1 http://www.androidchina.net/4177.html?utm_source=tuicool&utm_medium=referral Android开发中文站 »xUtils更新到3.0后的基本使用规则

9.2 http://blog.csdn.net/a1002450926/article/details/50364196

9.3 https://github.com/wyouflf/xUtils3 源码+sample

  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值