XUtils之ViewUtils和DBUtils

xutils简介:
xUtils 是一个工具类的集合体,其中包含许多实用的Android工具,主要包含四大模块: 

1、  ViewUtils的模块 
2、  DBUtils的模块 
3、  HttpUtils的模块  
4、  BitmapUtils的模块 

 
 
 xUitls最低兼容Android 2.2 (API 8)
下载地址:  https://github.com/wyouflf/xUtils,目前的版本是2.6.14
xutils3目前还不太稳定,不建议使用

ViewUtils:

java反射(Reflect)和注解( Annotation)的使用
反射:
在运行时状态,
对于任意一个类,知道这个类的属性和方法,
对于任意一个对象,访问它的任意一个属性和方法
动态获取类或者对象的信息以及动态调用对象方法
public class ReflectTest {
/**
* 使用反射调用公有方法,getMethod获取公有方法,类名要包含完整包名
* @return
*/
static int getAgeByReflectMethod(){
int age = 0;
try {
Class cls = Class.forName("com.qianfeng.zhouyi.xutilstest.Student");
Object obj = cls.newInstance();
Method setAgeMethod = cls.getMethod("setAge", int.class);
setAgeMethod.invoke(obj,10);

Method getAgeMethod = cls.getMethod("getAge");
age = (int) getAgeMethod.invoke(obj);

} catch (Exception e) {
Log.d("LessonXutils",e.getMessage());
}

return age;
}

/**使用反射访问私用属性,getDeclaredField能获取私有或公有属性,要调用setAccessible使其可以访问
*
* @return
*/
static int getAgeByReflectField(){
int age = 0;
try {
Class cls = Class.forName("com.qianfeng.zhouyi.xutilstest.Student");
Object obj = cls.newInstance();
Field fd = cls.getDeclaredField("age");
fd.setAccessible(true);
fd.set(obj,10);

age = (int) fd.get(obj);


} catch (Exception e) {
Log.d("LessonXutils",e.getMessage());
}

return age;
}

/**调用私有静态方法,getDeclaredMethod可以获取私有或公有方法,要调用setAccessible使其可以访问
* 静态方法不用newInstance得到对象
*
*/
static void invokeStaticMethod(){
try {
Class cls = Class.forName("com.qianfeng.zhouyi.xutilstest.Student");
Method staitcMethod = cls.getDeclaredMethod("test");
staitcMethod.setAccessible(true);
staitcMethod.invoke(cls);
} catch (Exception e) {
Log.d("LessonXutils", e.getMessage());
}

}


}

class Student{
private int age;
private String name;

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

private static void test(){
Log.d("LessonXutils","invoke test by reflect");
}
}
注解(Annotation):
   
   
  • 基本注解:
@Override:表示当前的方法定义将覆盖父类中的方法。 @Deprecated:使用了注解为它的元素编译器将发出警告,因为注解 @SupperssWarning 取消警告,比如@SuppressWarnings("deprecation")可以取消@Deprecated带来的警告
   
   
  • 元注解
修饰注解的注解,用于自定义注解
@Retention 表示在什么级别保存该注解
   RetentionPolicy.SOURCE - 对源代码有效,编译后丢弃
   RetentionPolicy.CLASS - 对class文件有效,运行时丢弃
   RetentionPolicy.RUNTIME - 内存中的字节码,在VM在运行时保留注解,才能够通过反射获取注解信息
@Target - 表示注解用在什么位置
   ElementType.FIELD - 用在成员变量,用在枚举属性
   ElementType.METHOD - 用在方法上
   ElementType.TYPE - 类或者接口,或者枚举
   ElementType.PACKAGE - 用在包上
   ElementType.LOCAL_VARIABLE - 局部变量
   ElementType.PARAMETER - 参数上
   
   
  • 自定义注解的实现和使用
定义一个注解
自定义一个注解,需要先使用元注解来声明注解的保留级别和应用位置
注解中可以包含属性,跟普通属性不一样,它类似于接口中的方法,可以设置默认值返回值
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)


public @interface MyAnnotation {
int value() default 10;
String name() default "Ann";
}
使用注解给属性赋值:
public class AnnotationTest {
//使用注解
@MyAnnotiaon(name="age",value = 12)
private int age;

//使用注入方式赋值
public static void inject(AnnotationTest test){
Class cls = AnnotationTest.class;

try {
Field field = cls.getDeclaredField("age");
field.setAccessible(true);

//可以直接赋值
//field.set(test,10);

//得到这个属性的注解,然后获取注解里的value,用这个value设置属性值
MyAnnotiaon ann = field.getAnnotation(MyAnnotiaon.class);
int iAge = ann.value();
field.set(test,iAge);

} catch (Exception e) {
e.printStackTrace();
}

}

public int getAge(){
return age;
}
}

Android中的ioc框架,完全注解方式就可以进行UI资源事件注入绑定
控制反转(Inversion of Control,英文缩写为 IoC):创建被调用者的工作不再由调用者来完成,因此称为控制反转。
使用注解和反射来实现控制反转(注入)
调用ViewUtils.inject(this),此方法中会利用反射遍历类中所有注解,对注解的功能一一实现
    
    
  • activity中Contentview的注解
@ContentView(value = R.layout.activity_main)
   
   
  • activity中View控件的注解
@ViewInject(R.id.btTest)
private Button mBtnTest;
   
   
  • activity中资源文件的注解
@ResInject(type = ResType.String,id = R.string.app_name)
String strAppName;
   
   
  • activity中事件的注解
@OnClick(R.id.btTest)
public void onClick(View view){
Toast.makeText(this,"onClick",Toast.LENGTH_SHORT).show();
}
   
   
  • fragment中的使用:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
// 加载布局
View view = inflater.inflate(R.layout.db_fragment, container, false);

// 依赖注入,第一个是用来反射获取注解,第二个参数用来findviewbyid
ViewUtils.inject(this, view);

return view;
}

@ViewInject(R.id.db_test_btn)
private Button stopBtn;

@ViewInject(R.id.result_txt)
private TextView resultText;

@OnClick(R.id.db_test_btn)
public void testDb(View view) {
}
   
   
  • BaseAdapter中的使用
protected class ViewHolder {
@ViewInject(R.id.tvItem)
public TextView tvItem;
}
注入的时候需要传2个参数,第一个是注解所在的类,为了获取注解,第二个是父view,为了调用findviewbyid得到注解所标记的view
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.layout_listitem, null);
ViewHolder viewHolder = new ViewHolder();
//viewHolder.tvItem = (TextView) convertView.findViewById(R.id.tvItem);

ViewUtils.inject(viewHolder,convertView);
convertView.setTag(viewHolder);
}
initializeViews((T)getItem(position), (ViewHolder) convertView.getTag());
return convertView;
}
@OnItemClick(R.id.lvTest)
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(this,"onItemClick",Toast.LENGTH_SHORT).show();
}



DBUtils 
  • 需要添加访问存储卡的权限
  • 定义数据表对应的类,必须是public的非内部类(单独一个类文件)
//指定表名,如果不用这个注解,表名默认为包名+类名
@Table(name="tbl_User")
public class User {
//主键,必须有,自增长
@Id
private int id;

//指定列名,如果不指定,就是字段名
//Unique注解代表字段唯一,不重复
@Column(column="username")
@Unique
private String name;

//column可以省略
//非空
@Column
@NotNull
private String email;

//规定年龄值的范围
@Check("20 <= age and age <= 130")
private int age;

//getxxx
//setxxx
//tostring
//......
常见的DB注解:
@Check    check约束
@ Column   列名
@ Id       主键,一般设置为int,自增长
@ NotNull  不为空
@ Table    表名
@ Unique   唯一约束


  • 创建数据库(指定路径时需要加入写文件权限)
/**
* 创建数据库,默认路径:/data/data/包名/database/xutils.db
*/
protected void createDb(){
mdbUtils = DbUtils.create(this);
}


/**
* 创建数据库,指定路径和数据库名
*/
protected void createDbWithDirName(){

String strPath = "/sdcard/";
Log.d("createDbWithDirName", "path=" + strPath);

mdbUtils = DbUtils.create(this, strPath, "mydb2");

}

/**
* 使用配置方式创建数据库
*/
protected void createDbWithConfig(){
DbUtils.DaoConfig daoConfig = new DbUtils.DaoConfig(this);
daoConfig.setDbDir("/sdcard/");
daoConfig.setDbName("mydb");

mdbUtils = DbUtils.create(daoConfig);
}

  • 创建数据表并插入数据
protected void createTableAndInsert(){
User user = new User();
user.setName("zhangsan");
user.setEmail("zhangsna@1000phone.com");
user.setAge(20);

User user2 = new User();
user2.setName("lisi");
user2.setEmail("lisi@1000phone.com");
user2.setAge(22);

List<User> listusers = new ArrayList<User>();
listusers.add(user);
listusers.add(user2);

try {
mdbUtils.saveAll(listusers);

} catch (DbException e) {
Log.d("LessonDbUtils",e.getMessage());
}
}

  • 查询数据
查询所有数据:
protected void queryData(){

try {
List<User> listUsers = mdbUtils.findAll(User.class);
Log.d("queryData", listUsers.toString());
} catch (DbException e) {
e.printStackTrace();
}

}
条件查询:

protected void query() {
try {
List<User> users = dbUtils.findAll(com.lidroid.xutils.db.sqlite.Selector.from(User.class)
.where("age", "=", "29")
.or("age","=","28")

);
Log.d("qf", users.toString());

} catch (Exception e) {
Log.e("qf", e.toString());
}
}
sql语句查询:
protected void query() {
List<User> listUsers = new ArrayList<>();

Cursor cursor = MyApplication.mDbUtils.execQuery("select * from tbl_user");
int iNameIndex = cursor.getColumnIndex("username");
int iEmailIndex = cursor.getColumnIndex("email");
int iAgeIndex = cursor.getColumnIndex("age");
int iIdIndex = cursor.getColumnIndex("id");


while (cursor.moveToNext()){
User user = new User();
String strUserName = cursor.getString(iNameIndex);
String strEmail = cursor.getString(iEmailIndex);
int iAge = cursor.getInt(iAgeIndex);
int iId = cursor.getInt(iIdIndex);
user.setAge(iAge);
user.setEmail(strEmail);
user.setName(strUserName);
user.setId(iId);

listUsers.add(user);
}

cursor.close();


Log.d("qf",listUsers.toString());

} catch (DbException e) {
e.printStackTrace();
Log.e("qf",e.getMessage());
}
}




  • 更新数据
更新单条数据:
protected void updateData(){
try {
User user = mdbUtils.findById(User.class, 2);
user.setAge(32);
mdbUtils.update(user, "age");
} catch (DbException e) {
e.printStackTrace();
}
}
按条件更新:
protected void update(){
try {

User user = new User();
user.setAge(40);

dbUtils.update(user, WhereBuilder.b("id",">","0"),"age");

} catch (DbException e) {
Log.e("qf", e.toString());
}
}
批量更新数据,对象中必须设置id,以id为索引,更新指定列的值
protected void update(){
try {

User user = new User();
user.setId(1);
user.setAge(30);

User user1 = new User();
user1.setId(2);
user1.setAge(30);

List<User> users = new ArrayList<>();
users.add(user);
users.add(user1);

dbUtils.updateAll(users,"age");

} catch (DbException e) {
Log.e("qf", e.toString());
}
}
sql语句更新数据:
protected void update(){
try {
dbUtils.execNonQuery("update table_user set age = 35 where id = 1");
} catch (DbException e) {
Log.e("qf", e.toString());
}
}


  • 删除数据
protected void deleteData(){
User user = new User();
user.setId(2);
try {
mdbUtils.delete(user);
} catch (DbException e) {
e.printStackTrace();
}

}

练习——72g手游助手,选一个页面,对网络数据在数据库中做缓存,打开界面的时候,如果判断没有网络,把缓存在数据库中的内容显示出来
判断网络是否连接好:

// 检测网络
public static boolean checkNetworkAvailable(Context context) {
ConnectivityManager connectivity = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivity == null) {
return false;
} else {
NetworkInfo[] info = connectivity.getAllNetworkInfo();
if (info != null) {
for (int i = 0; i < info.length; i++) {
if (info[i].getState() == NetworkInfo.State.CONNECTED) {
NetworkInfo netWorkInfo = info[i];
if (netWorkInfo.getType() == ConnectivityManager.TYPE_WIFI) {
return true;
} else if (netWorkInfo.getType() == ConnectivityManager.TYPE_MOBILE) {
return true;
}
}
}
}
}
return false;
}
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值