一.xUtils框架简介
xUtils 最初源于Afinal框架,进行了大量重构,使得xUtils支持大文件上传,更全面的http请求协议支持(10种谓词),拥有更加灵活的ORM,更多的事件注解支持且不受混淆影响…
xUtils最低兼容android 2.2 (api level 8)。
当前xUtils主要有四大模块:
1.DbUtils模块
2.ViewUtils模块
3.HttpUtils模块
4.BitmapUtils模块
二.DbUtils模块
简介
- android中的orm框架,一行代码就可以进行增删改查。
- 支持事务,默认关闭。
- 可通过注释自定义表名,列名,外键,唯一约束,NOT NULL约束,CHECK约束等(需要混淆的时候请注解表名和列名)。
- 支持绑定外键,保存实体时外键关联实体自动保存或更新。
- 自动加载外键关联实体,支持延时加载。
- 支持链式表达查询,更直观的查询语义。
实例
权限所需
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.xiaofei.app.xutils.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:id="@+id/textView" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="添加数据"
android:id="@+id/button_save"
android:onClick="saveClick"
android:layout_below="@+id/textView"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="查询所有"
android:id="@+id/button_findAll"
android:onClick="findAllClick"
android:layout_below="@+id/button_save"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignRight="@+id/button_save"
android:layout_alignEnd="@+id/button_save" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="查找单个"
android:id="@+id/button"
android:onClick="selectByClick"
android:layout_below="@+id/button_findAll"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="更新"
android:onClick="updateClick"
android:id="@+id/button2"
android:layout_below="@+id/button"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="删除"
android:onClick="deleteClick"
android:id="@+id/button3"
android:layout_below="@+id/button2"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
</RelativeLayout>
MainActivity.java
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Toast;
import com.lidroid.xutils.DbUtils;
import com.lidroid.xutils.db.sqlite.Selector;
import com.lidroid.xutils.db.sqlite.WhereBuilder;
import com.lidroid.xutils.exception.DbException;
import java.util.List;
public class MainActivity extends AppCompatActivity {
DbUtils db;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
db = DbUtils.create(this,"mydb");
}
public void saveClick(View view)
{
User user=new User("123456@qq.com","xiaohong");
try {
db.save(user);
Toast.makeText(MainActivity.this,"save success",Toast.LENGTH_LONG).show();
} catch (DbException e) {
e.printStackTrace();
}
}
public void findAllClick(View view)
{
try {
List<User> list=db.findAll(User.class);
for (User u:list)
{
System.out.println(u);
}
} catch (DbException e) {
e.printStackTrace();
}
}
public void selectByClick(View view)
{
try {
User user = db.findFirst(Selector.from(User.class).where("name","=","xiaohong"));
Toast.makeText(this,user.toString(),Toast.LENGTH_LONG).show();
} catch (DbException e) {
e.printStackTrace();
}
}
public void updateClick(View view)
{
User user=new User();
user.setId(1);
user.setEmail("*********@qq.com");
user.setName("xiaoming");
try {
db.update(user,"email","name");
Toast.makeText(this,"更新成功",Toast.LENGTH_LONG).show();
} catch (DbException e) {
e.printStackTrace();
}
}
public void deleteClick(View view)
{
try {
db.delete(User.class, WhereBuilder.b("id","=","1"));
Toast.makeText(this,"删除成功",Toast.LENGTH_LONG).show();
} catch (DbException e) {
e.printStackTrace();
}
}
}
User.java
public class User {
private int id;
private String name;
private String email;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public User(String email, String name) {
this.email = email;
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public User() {
}
@Override
public String toString() {
return "User{" +
"email='" + email + '\'' +
", id=" + id +
", name='" + name + '\'' +
'}';
}
}
三.ViewUtils模块
简介
- 完全注解方式就可以进行UI绑定和事件绑定。
- 无需findViewById和setClickListener等。
实例
// xUtils的view注解要求必须提供id,以使代码混淆不受影响。
@ViewInject(R.id.textView)
TextView textView;
//@ViewInject(vale=R.id.textView, parentId=R.id.parentView)
//TextView textView;
@ResInject(id = R.string.label, type = ResType.String)
private String label;
// 取消了之前使用方法名绑定事件的方式,使用id绑定不受混淆影响
// 支持绑定多个id @OnClick({R.id.id1, R.id.id2, R.id.id3})
// or @OnClick(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。
@OnClick(R.id.test_button)
public void testButtonClick(View v) { // 方法签名必须和接口中的要求一致
...
}
...
//在Activity中注入:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ViewUtils.inject(this); //注入view和事件
...
textView.setText("some text...");
...
}
//在Fragment中注入:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.bitmap_fragment, container, false); // 加载fragment布局
ViewUtils.inject(this, view); //注入view和事件
...
}
//在PreferenceFragment中注入:
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
ViewUtils.inject(this, getPreferenceScreen()); //注入view和事件
...
}
// 其他重载
// inject(View view);
// inject(Activity activity)
// inject(PreferenceActivity preferenceActivity)
// inject(Object handler, View view)
// inject(Object handler, Activity activity)
// inject(Object handler, PreferenceGroup preferenceGroup)
// inject(Object handler, PreferenceActivity preferenceActivity)
四.HttpUtils模块
简介
- 支持同步,异步方式的请求
- 支持大文件上传,上传大文件不会oom;
- 支持GET,POST,MOVE,COPY,DELETE,HEAD,OPTIONS,TRACE,CONNECT请求;
- 下载支持301/302重定向,支持设置是否根据Content-Disposition重命名下载的文件;
- 返回文本内容的请求(默认只启用GET请求)支持缓存,可设置默认过期时间和针对当前请求的过期时间。
实例
所需jar包
权限
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
JsonObject.java
import java.util.ArrayList;
public class JsonObject {
private String login;
private ArrayList<User> user=new ArrayList<User>();
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
public ArrayList<User> getUser() {
return user;
}
public void setUser(ArrayList<User> user) {
this.user = user;
}
@Override
public String toString() {
return "JsonObject{" +
"login='" + login + '\'' +
", user=" + user +
'}';
}
}
User.java
public class User {
private int id;
private String username;
private String password;
private String role;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
public User(int id,String username, String password, String role) {
this.id=id;
this.username = username;
this.password = password;
this.role = role;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", role='" + role + '\'' +
'}';
}
public User()
{
}
}
MainActivity2.java
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import com.google.gson.Gson;
import com.lidroid.xutils.HttpUtils;
import com.lidroid.xutils.exception.HttpException;
import com.lidroid.xutils.http.RequestParams;
import com.lidroid.xutils.http.ResponseInfo;
import com.lidroid.xutils.http.callback.RequestCallBack;
import com.lidroid.xutils.http.client.HttpRequest;
import java.util.ArrayList;
public class MainActivity2 extends Activity {
private EditText editText_username;
private EditText editText_password;
private Button button_login;
private TextView textView_info;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
editText_username= (EditText) findViewById(R.id.editText_username);
editText_password= (EditText) findViewById(R.id.editText_password);
button_login= (Button) findViewById(R.id.button_login);
textView_info=(TextView)findViewById(R.id.info);
button_login.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String username=editText_username.getText().toString();
String password=editText_password.getText().toString();
HttpUtils httpUtils=new HttpUtils();
String url="http://192.168.1.101:8080/user/LoginServlet";
RequestParams params=new RequestParams();
params.addQueryStringParameter("username",username);
params.addBodyParameter("password",password);
httpUtils.send(HttpRequest.HttpMethod.POST, url, params, new RequestCallBack<String>() {
@Override
public void onStart() {
super.onStart();
textView_info.setText("conn...");
}
@Override
public void onLoading(long total, long current, boolean isUploading) {
super.onLoading(total, current, isUploading);
if (isUploading) {
textView_info.setText("upload: " + current + "/" + total);
} else {
textView_info.setText("reply: " + current + "/" + total);
}
}
@Override
public void onSuccess(ResponseInfo<String> responseInfo) {
String result=responseInfo.result;
System.out.println(result);
Gson gson = new Gson();
JsonObject object = gson.fromJson(result, JsonObject.class);
ArrayList<User> list=object.getUser();
int count=list.size();
String username="";
for (int i=0;i<count;i++)
{
username=username+list.get(i).getUsername();
}
textView_info.setText(username);
}
@Override
public void onFailure(HttpException error, String msg) {
textView_info.setText(error.getExceptionCode() + ":" + msg);
}
});
}
});
}
//用来解析JSON为对象
public void jsonToObject(String json) {
Gson gson = new Gson();
JsonObject object = gson.fromJson(json, JsonObject.class);
// info.setText(object.toString());
System.out.println(object.toString());
textView_info.setText(object.toString());
}
}
activity_main2.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.xiaofei.app.xutils.MainActivity2">
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/editText_username"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentRight="true"
android:hint="input username"
android:layout_alignParentEnd="true" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/editText_password"
android:layout_below="@+id/editText_username"
android:layout_alignParentLeft="true"
android:hint="inout password"
android:layout_alignParentStart="true"
android:layout_alignRight="@+id/editText_username"
android:layout_alignEnd="@+id/editText_username" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="登录"
android:id="@+id/button_login"
android:layout_below="@+id/editText_password"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignRight="@+id/editText_password"
android:layout_alignEnd="@+id/editText_password" />
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="New Text"
android:id="@+id/info"
android:layout_below="@+id/button_login"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
</RelativeLayout>
五.BitmapUtils模块
简介
- 加载bitmap的时候无需考虑bitmap加载过程中出现的oom和android容器快速滑动时候出现的图片错位等现象;
- 支持加载网络图片和本地图片;
- 内存管理使用lru算法,更好的管理bitmap内存;
- 可配置线程加载线程数量,缓存大小,缓存路径,加载显示动画等…
实例
所需jar包
需要Bmob云服务中存有数据
product.java
import cn.bmob.v3.BmobObject;
import cn.bmob.v3.datatype.BmobFile;
public class product extends BmobObject{
private String name;
private BmobFile pic;
private double price;
private double discount;
public product()
{
}
public product(String name, BmobFile pic, double price, double discount) {
this.name = name;
this.pic = pic;
this.price = price;
this.discount = discount;
}
public double getDiscount() {
return discount;
}
public void setDiscount(double discount) {
this.discount = discount;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public BmobFile getPic() {
return pic;
}
public void setPic(BmobFile pic) {
this.pic = pic;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
}
ProductListAdapter.java
import android.content.Context;
import android.os.Environment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.lidroid.xutils.BitmapUtils;
import java.util.List;
public class ProductListAdapter extends BaseAdapter {
private Context context;
private List<product> products;
public ProductListAdapter(Context context, List<product> products) {
this.context = context;
this.products = products;
}
public List<product> getProducts() {
return products;
}
public void setProducts(List<product> products) {
this.products = products;
}
@Override
public int getCount() {
return products.size();
}
@Override
public Object getItem(int position) {
return products.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder vh;
if (convertView == null) {
convertView = LayoutInflater.from(context).inflate(R.layout.product_list_item, null);
vh = new ViewHolder();
vh.textView_name = (TextView) convertView.findViewById(R.id.textView_name);
vh.textView_price = (TextView) convertView.findViewById(R.id.textView_price);
vh.textView_discount = (TextView) convertView.findViewById(R.id.textView_discount);
vh.imageView_product_image = (ImageView) convertView.findViewById(R.id.imageView_product_image);
convertView.setTag(vh);
}
vh = (ViewHolder) convertView.getTag();
product p = products.get(position);
vh.textView_name.setText(p.getName());
vh.textView_price.setText("¥" + Math.round((p.getPrice() * (p.getDiscount() / 10) * 100.00)) / 100.00);
vh.textView_discount.setText(String.valueOf(p.getDiscount()) + "折");
//用于缓存图片文件 Lru算法
//用于缓存图片文件 Lru算法
String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + "/x-utils";
BitmapUtils bitmapUtils = new BitmapUtils(context, path);
bitmapUtils.configDefaultBitmapMaxSize(100, 100);
bitmapUtils.display(vh.imageView_product_image, p.getPic().getFileUrl(context));
return convertView;
}
static class ViewHolder {
TextView textView_name;
TextView textView_price;
TextView textView_discount;
ImageView imageView_product_image;
}
}
ProductListActivity.java
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ListView;
import java.util.ArrayList;
import java.util.List;
import cn.bmob.v3.Bmob;
import cn.bmob.v3.BmobQuery;
import cn.bmob.v3.listener.FindListener;
public class ProductListActivity extends AppCompatActivity {
private ListView productListView;
private ProductListAdapter pla;
private List<product> products=new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_product_list);
// 初始化 Bmob SDK
// 使用时请将第二个参数Application ID替换成你在Bmob服务器端创建的Application ID
Bmob.initialize(this, "Application ID");
productListView=(ListView)findViewById(R.id.product_list_view);
pla=new ProductListAdapter(ProductListActivity.this,products);
loadData();
}
private void loadData()
{
final View loadView=getLayoutInflater().inflate(R.layout.load_data,null);
productListView.addHeaderView(loadView);
productListView.setAdapter(pla);
BmobQuery<product> query=new BmobQuery<>();
query.findObjects(ProductListActivity.this, new FindListener<product>() {
@Override
public void onSuccess(List<product> list) {
System.out.println(list.size());
products=list;
productListView.removeHeaderView(loadView);
pla.setProducts(products);
pla.notifyDataSetChanged();
}
@Override
public void onError(int i, String s) {
}
});
}
}
button_bg.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@color/colorAccent"
android:state_pressed="true">
</item>
<item android:drawable="@color/colorPrimary"></item>
</selector>
load_data.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/progressBar"
style="?android:attr/progressBarStyleSmall"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="正在玩命加载中..."
android:id="@+id/textView"/>
</LinearLayout>
product_list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="100dp"
android:layout_height="wrap_content"
android:id="@+id/imageView_product_image"
android:src="@mipmap/ic_launcher"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignBottom="@+id/button" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="产品标题部分内容"
android:id="@+id/textView_name"
android:layout_alignParentTop="true"
android:layout_toRightOf="@+id/imageView_product_image"
android:layout_toEndOf="@+id/imageView_product_image" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="去购买"
android:background="@drawable/button_bg"
android:id="@+id/button"
android:layout_below="@+id/textView_name"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="¥97.00"
android:id="@+id/textView_price"
android:layout_alignBottom="@+id/imageView_product_image"
android:layout_toRightOf="@+id/imageView_product_image"
android:layout_toEndOf="@+id/imageView_product_image" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="折扣"
android:id="@+id/textView_discount"
android:layout_alignBaseline="@+id/button"
android:layout_alignBottom="@+id/button"
android:layout_toRightOf="@+id/textView_name"
android:layout_toEndOf="@+id/textView_name" />
</RelativeLayout>
activity_product_list.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".ProductListActivity">
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/product_list_view"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
</RelativeLayout>