转载自:http://blog.csdn.net/smartbetter/article/details/51866792
1.先来认识一下xUtils3
1)xUtils3简介
xUtils是目前功能比较完善的一个Android开源框架,最近又发布了xUtil3.0,在增加新功能的同时又提高了框架的性能,下面来看看官方(https://github.com/wyouflf/xUtils3)对xUtils3的介绍:
xUtils包含了很多实用的android工具;
xUtils支持超大文件(超过2G)上传,更全面的http请求协议支持(11种谓词),拥有更加灵活的ORM,更多的事件注解支持且不受混淆影响;
xUtils 最低兼容Android 4.0 (api level 14);
xUtils3变化较多所以建立了新的项目不在旧版(github.com/wyouflf/xUtils)上继续维护, 相对于旧版本:
HTTP实现替换HttpClient为UrlConnection, 自动解析回调泛型, 更安全的断点续传策略;
支持标准的Cookie策略, 区分domain, path;
事件注解去除不常用的功能, 提高性能;
数据库api简化提高性能, 达到和greenDao一致的性能;
图片绑定支持gif(受系统兼容性影响, 部分gif文件只能静态显示), webp; 支持圆角, 圆形, 方形等裁剪, 支持自动旋转。
2)在我们的项目中快速配置xUtils3
xUtils3的配置十分的简单:
2-1)使用Gradle构建时添加一下依赖即可
compile'org.xutils:xutils:3.3.36'
如果使用eclipse可以点击下面链接下载aar文件, 然后用zip解压,取出jar包和so文件。
Github下载:https://github.com/wyouflf/xUtils3
JCenter下载:http://jcenter.bintray.com/org/xutils/xutils/
Maven下载1:http://central.maven.org/maven2/org/xutils/xutils/
Maven下载2:http://repo1.maven.org/maven2/org/xutils/xutils/
2-2)加入权限
2-3)创建Application
public class MyApp extends Application{
@Override public void onCreate() {
super.onCreate();
x.Ext.init(this);
x.Ext.setDebug(false);//输出debug日志,开启会影响性能
}}
2-4)在AndroidManifest文件中注册MyApp
xUtils3主要包含注解模块、网络模块、图片模块和数据库模块,下面将做一一说明。
xUtils3注解模块在实际开发中的使用如下:
1)Activity的注解的使用如下:
2)Fragment的注解的使用如下:
3)为按钮设置点击事件
方法必须私有限定,
方法参数形式必须和type对应的Listener接口一致.
注解参数value支持数组: value={id1, id2, id3}
强调:使用注解模块一定要注意初始化视图注解框架。
xUtils3网络模块大大方便了在实际开发中网络模块的开发,xUtils3网络模块大致包括GET请求、POST请求、如何使用其他请求方式、上传文件、下载文件、使用缓存等功能,下面将做一一说明:
1)GET请求
下面我们来看下带有缓存的GET请求,POST请求和其他请求方式类似,后面就不再赘述:
带有缓存的GET请求:
RequestParams params =newRequestParams(url);params.addQueryStringParameter("username","abc");params.addQueryStringParameter("password","123");// 默认缓存存活时间, 单位:毫秒(如果服务器没有返回有效的max-age或Expires则参考)params.setCacheMaxAge(1000*60);x.http().get(params,newCallback.CacheCallback() {privatebooleanhasError =false;privateString result =null;@OverridepublicbooleanonCache(String result) {//得到缓存数据, 缓存过期后不会进入this.result = result;returntrue;//true: 信任缓存数据, 不再发起网络请求; false不信任缓存数据}@OverridepublicvoidonSuccess(String result) {//如果服务返回304或onCache选择了信任缓存,这时result为nullLog.i("JAVA","开始请求");if(result !=null) {this.result = result; } }@OverridepublicvoidonError(Throwable ex,booleanisOnCallback) { hasError =true; Toast.makeText(x.app(), ex.getMessage(), Toast.LENGTH_LONG).show();if(exinstanceofHttpException) {//网络错误HttpException httpEx = (HttpException) ex;intresponseCode = httpEx.getCode(); String responseMsg = httpEx.getMessage(); String errorResult = httpEx.getResult();//...}else{//其他错误//...} }@OverridepublicvoidonCancelled(CancelledException cex) { }@OverridepublicvoidonFinished() {if(!hasError && result !=null) {//成功获取数据Toast.makeText(x.app(), result, Toast.LENGTH_LONG).show(); } }});
上面onCache方法中需要注意的几点:
a)如果服务端没有返回过期时间,参考params.setCacheMaxAge(maxAge)方法。
b)客户端会根据服务端返回的header中max-age或expires来确定本地缓存是否给onCache方法。如果服务端没有返回max-age或expires,那么缓存将一直保存,除非这里自己定义了返回false,那么xUtils将请求新数据, 来覆盖它。
c)如果信任该缓存返回true,将不再请求网络。返回false继续请求网络,但会在请求头中加上ETag,Last-Modified等信息。如果服务端返回304,则表示数据没有更新,不继续加载数据。
2)POST请求
RequestParamsparams=newRequestParams(url);params.addBodyParameter("username","abc");params.addParameter("password","123");params.addHeader("head","android");//为当前请求添加一个头x.http().post(params,newCallback.CommonCallback() { @OverridepublicvoidonSuccess(String result) {//解析result} @OverridepublicvoidonError(Throwable ex, boolean isOnCallback) { } @OverridepublicvoidonCancelled(CancelledException cex) { } @OverridepublicvoidonFinished() { }});
3)其他网络请求方式
RequestParams params =newRequestParams(url);params.addParameter("username","abc");x.http().request(HttpMethod.PUT, params,newCallback.CommonCallback() {@OverridepublicvoidonSuccess(String result) {//解析result}@OverridepublicvoidonError(Throwable ex,booleanisOnCallback) { }@OverridepublicvoidonCancelled(CancelledException cex) { }@OverridepublicvoidonFinished() { }});
4)上传文件
String path="/mnt/sdcard/Download/icon.jpg";RequestParams params =newRequestParams(url);params.setMultipart(true);params.addBodyParameter("file",newFile(path));x.http().post(params,newCallback.CommonCallback() {@OverridepublicvoidonSuccess(String result) { }@OverridepublicvoidonError(Throwable ex,booleanisOnCallback) { }@OverridepublicvoidonCancelled(CancelledException cex) { }@OverridepublicvoidonFinished() { }});
5)下载文件
这里以下载apk为例进行说明,apk下载完成后,自动调用系统的安装方法。
url ="http://127.0.0.1/server/abc.apk";RequestParams params =newRequestParams(url);//自定义保存路径,Environment.getExternalStorageDirectory():SD卡的根目录params.setSaveFilePath(Environment.getExternalStorageDirectory()+"/myapp/");//自动为文件命名params.setAutoRename(true);x.http().post(params,newCallback.ProgressCallback() {@OverridepublicvoidonSuccess(File result) {//apk下载完成后,调用系统的安装方法Intent intent =newIntent(Intent.ACTION_VIEW); intent.setDataAndType(Uri.fromFile(result),"application/vnd.android.package-archive"); getActivity().startActivity(intent); }@OverridepublicvoidonError(Throwable ex,booleanisOnCallback) { }@OverridepublicvoidonCancelled(CancelledException cex) { }@OverridepublicvoidonFinished() { }//网络请求之前回调@OverridepublicvoidonWaiting() { }//网络请求开始的时候回调@OverridepublicvoidonStarted() { }//下载的时候不断回调的方法@OverridepublicvoidonLoading(longtotal,longcurrent,booleanisDownloading) {//当前进度和文件总大小Log.i("JAVA","current:"+ current +",total:"+total); }});
xUtils3图片模块,重点在于加载图片的4个bind方法,loadDrawable与loadFIle用法和ImageOptions用法,需多加练习。
1)xUtils3 ImageOptions:
//通过ImageOptions.Builder().set方法设置图片的属性ImageOptions imageOptions=newImageOptions.Builder().setFadeIn(true).build();//淡入效果//ImageOptions.Builder()的一些其他属性:.setCircular(true)//设置图片显示为圆形.setSquare(true)//设置图片显示为正方形.setCrop(true).setSize(200,200)//设置大小.setAnimation(animation)//设置动画.setFailureDrawable(Drawable failureDrawable)//设置加载失败的动画.setFailureDrawableId(intfailureDrawable)//以资源id设置加载失败的动画.setLoadingDrawable(Drawable loadingDrawable)//设置加载中的动画.setLoadingDrawableId(intloadingDrawable)//以资源id设置加载中的动画.setIgnoreGif(false)//忽略Gif图片.setParamsBuilder(ParamsBuilder paramsBuilder)//在网络请求中添加一些参数.setRaduis(intraduis)//设置拐角弧度.setUseMemCache(true)//设置使用MemCache,默认true
2)xUtils3 bind方法:
// assets filex.image().bind(imageView,"assets://test.gif", imageOptions);// local filex.image().bind(imageView,newFile("/sdcard/test.gif").toURI().toString(), imageOptions);x.image().bind(imageView,"/sdcard/test.gif", imageOptions);x.image().bind(imageView,"file:///sdcard/test.gif", imageOptions);x.image().bind(imageView,"file:/sdcard/test.gif", imageOptions);x.image().bind(imageView, url, imageOptions,newCallback.CommonCallback() {@OverridepublicvoidonSuccess(Drawable result) { }@OverridepublicvoidonError(Throwable ex,booleanisOnCallback) { }@OverridepublicvoidonCancelled(CancelledException cex) { }@OverridepublicvoidonFinished() { }
3)xUtils3 loadDrawable方法:
x.image().loadDrawable(url, imageOptions,newCallback.CommonCallback() {@OverridepublicvoidonSuccess(Drawable result) { imageView.setImageDrawable(result); }@OverridepublicvoidonError(Throwable ex,booleanisOnCallback) { }@OverridepublicvoidonCancelled(CancelledException cex) { }@OverridepublicvoidonFinished() { }});
4)xUtils3 loadFile方法:
当我们通过bind()或者loadDrawable()方法加载了一张图片后,它会保存到本地文件中,那当我需要这张图片时,就可以通过loadFile()方法进行查找。
x.image().loadFile(url,imageOptions,newCallback.CacheCallback(){@OverridepublicbooleanonCache(File result) {//在这里可以做图片另存为等操作Log.i("JAVA","file:"+result.getPath()+result.getName());returntrue;//相信本地缓存返回true}@OverridepublicvoidonSuccess(File result) { }@OverridepublicvoidonError(Throwable ex,booleanisOnCallback) { }@OverridepublicvoidonCancelled(CancelledException cex) { }@OverridepublicvoidonFinished() { }});
1)初始化配置和创建实体类
首先在项目Application中进行初始化配置DaoConfig(与onCreate方法同级目录下):
/**
* 初始化DaoConfig配置
*/DbManager.DaoConfig daoConfig =newDbManager.DaoConfig()//设置数据库名,默认xutils.db.setDbName("myapp.db")//设置数据库路径,默认存储在app的私有目录.setDbDir(newFile("/mnt/sdcard/"))//设置数据库的版本号.setDbVersion(2)//设置数据库打开的监听.setDbOpenListener(newDbManager.DbOpenListener() {@OverridepublicvoidonDbOpened(DbManager db) {//开启数据库支持多线程操作,提升性能,对写入加速提升巨大db.getDatabase().enableWriteAheadLogging(); } })//设置数据库更新的监听.setDbUpgradeListener(newDbManager.DbUpgradeListener() {@OverridepublicvoidonUpgrade(DbManager db,intoldVersion,intnewVersion) { } })//设置表创建的监听.setTableCreateListener(newDbManager.TableCreateListener() {@OverridepublicvoidonTableCreated(DbManager db, TableEntity table){ Log.i("JAVA","onTableCreated:"+ table.getName()); } });//设置是否允许事务,默认true//.setAllowTransaction(true)DbManager db = x.getDb(daoConfig);
然后创建数据库表ChildInfo的实体类:
/**
* onCreated = "sql":当第一次创建表需要插入数据时候在此写sql语句
*/@Table(name ="child_info",onCreated ="")publicclassChildInfo{/**
* name = "id":数据库表中的一个字段
* isId = true:是否是主键
* autoGen = true:是否自动增长
* property = "NOT NULL":添加约束
*/@Column(name ="id",isId =true,autoGen =true,property ="NOT NULL")privateintid;@Column(name ="c_name")privateString cName;publicChildInfo(String cName) {this.cName = cName; }//默认的构造方法必须写出,如果没有,这张表是创建不成功的publicChildInfo() { }publicintgetId() {returnid; }publicvoidsetId(intid) {this.id = id; }publicStringgetcName() {returncName; }publicvoidsetcName(String cName) {this.cName = cName; }@OverridepublicStringtoString() {return"ChildInfo{"+"id="+id+",cName='"+cName+'\''+'}'; }}
之后就能进行创建和删除数据库的操作了:
2)创建数据库
//用集合向child_info表中插入多条数据ArrayList childInfos =newArrayList<>();childInfos.add(newChildInfo("zhangsan"));childInfos.add(newChildInfo("lisi"));childInfos.add(newChildInfo("wangwu"));childInfos.add(newChildInfo("zhaoliu"));childInfos.add(newChildInfo("qianqi"));childInfos.add(newChildInfo("sunba"));//db.save()方法不仅可以插入单个对象,还能插入集合db.save(childInfos);
3)删除数据库
db.dropDb();
4)删除表
db.dropTable(ChildInfo.class);
5)新增表中的数据
ChildInfo childInfo =newChildInfo("zhangsan123");db.save(childInfo);
6)删除表中的数据
//第一种写法:db.delete(ChildInfo.class);//child_info表中数据将被全部删除//第二种写法,添加删除条件:WhereBuilder b = WhereBuilder.b();b.and("id",">",2);//构造修改的条件b.and("id","<",4);db.delete(ChildInfo.class, b);
7)修改表中的数据
//第一种写法:ChildInfo first = db.findFirst(ChildInfo.class);first.setcName("zhansan2");db.update(first,"c_name"); //c_name:表中的字段名//第二种写法:WhereBuilder b = WhereBuilder.b();b.and("id","=",first.getId()); //构造修改的条件KeyValue name = new KeyValue("c_name","zhansan3");db.update(ChildInfo.class,b,name);//第三种写法:first.setcName("zhansan4");db.saveOrUpdate(first);
8)查询表中的数据
//查询数据库表中第一条数据ChildInfo first = db.findFirst(ChildInfo.class);Log.i("JAVA",first.toString());//添加查询条件进行查询List all = db.selector(ChildInfo.class).where("id",">",2).and("id","<",4).findAll();for(ChildInfo childInfo :all){ Log.i("JAVA",childInfo.toString());}
1)UI异步执行
x.task().run(newRunnable() {@Overridepublicvoidrun() {//异步代码}});
2)UI同步执行
x.task().post(newRunnable() {@Overridepublicvoidrun() {//同步代码}});