反射机制及开源框架xUitls的使用,使用HttpUtils通过断点续传下载文件

反射:

Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法

对于任意一个对象,都能够调用它的任意一个方法和属性

Java反射机制主要提供下面几种用途:

1•在运行时判断任意一个对象所属的类

2•在运行时构造任意一个类的对象

3•在运行时判断任意一个类所具有的成员变量和方法

4•在运行时调用任意一个对象的方法

第一步 得到某个类的class对象,有三种方式;

方式一:  Class<Student> class1 = Student.class;

方式二:  Class class2 = Class.forName("包名");

方式三:  Student student = new Student();
       Class class3 = student.getClass();

然后我们就可以对类中的方法属性进行操作了..

访问类中的属性了,属性包括了私有公有的属性

            Field fields[] = class1.getDeclaredFields();
for (Field field : fields) {
System.out.println(field);
}

通过反射创建对象

      //1.得到无参构造方法
Constructor<Student> constructor = class1.getConstructor();
//2.创建对象
Student stu = constructor.newInstance();
//等价于Student stu = new Student();

调用set方法设置数据

            Method method = class1.getDeclaredMethod("setName", new Class[]{String.class});
//私有方法需要设置权限
method.setAccessible(true);
//2.通过之前的student对象调用setName表示的方法
method.invoke(stu, new Object[]{"张三"});

通过Get方法得到数据

Method getName = class1.getDeclaredMethod("getName", new Class[]{});
//通过之前的student对象调用getName表示的方法
Object object = getName.invoke(stu, new Object[]{});
System.out.println(object);

第三方框架XUitls的使用:
  下载XUils   地址:https://github.com/wyouflf/xUtils

  导入项目,将jar包复制到当前工程下的libs目录下---点击该jar包-右键--As a Library --ok

  • xUtils 包含了很多实用的android工具。
  • xUtils 支持大文件上传,更全面的http请求协议支持(10种谓词),拥有更加灵活的ORM,更多的事件注解支持且不受混淆影响...
  • xUitls 最低兼容android 2.2 (api level 8)

目前xUtils主要有四大模块:

  • DbUtils模块:

    • android中的orm框架,一行代码就可以进行增删改查;
    • 支持事务,默认关闭;
    • 可通过注解自定义表名,列名,外键,唯一性约束,NOT NULL约束,CHECK约束等(需要混淆的时候请注解表名和列名);
    • 支持绑定外键,保存实体时外键关联实体自动保存或更新;
    • 自动加载外键关联实体,支持延时加载;
    • 支持链式表达查询,更直观的查询语义,参考下面的介绍或sample中的例子。
  • ViewUtils模块:

    • android中的ioc框架,完全注解方式就可以进行UI,资源和事件绑定;
    • 新的事件绑定方式,使用混淆工具混淆后仍可正常工作;
    • 目前支持常用的20种事件绑定,参见ViewCommonEventListener类和包com.lidroid.xutils.view.annotation.event。
  • HttpUtils模块:

    • 支持同步,异步方式的请求;
    • 支持大文件上传,上传大文件不会oom;
    • 支持GET,POST,PUT,MOVE,COPY,DELETE,HEAD,OPTIONS,TRACE,CONNECT请求;
    • 下载支持301/302重定向,支持设置是否根据Content-Disposition重命名下载的文件;
    • 返回文本内容的请求(默认只启用了GET请求)支持缓存,可设置默认过期时间和针对当前请求的过期时间。
  • BitmapUtils模块:

    • 加载bitmap的时候无需考虑bitmap加载过程中出现的oom和android容器快速滑动时候出现的图片错位等现象;
    • 支持加载网络图片和本地图片;
    • 内存管理使用lru算法,更好的管理bitmap内存;
    • 可配置线程加载线程数量,缓存大小,缓存路径,加载显示动画等...
    • 使用xUtils快速开发框架需要有以下权限:

      <uses-permission android:name="android.permission.INTERNET" />
      <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

ViewUtils使用方法

API:http://xutilsapi.oschina.mopaas.com/

  • 完全注解方式就可以进行UI绑定和事件绑定。
  • 无需findViewById和setClickListener等。

注解:从原理上讲,注解处理器就是通过反射机制获取被检查方法上的注解信息,然后根据注解元素的值进行特定的处理。

首先需要在activity中注入:(否则控件,资源,,注入没用)

//在Activity中注入:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ViewUtils.inject(this); //注入view和事件
...
textView.setText("some text...");
注入布局:相当于setContentView(R.layout.activity_main);
@ContentView(R.layout.activity_main)
public class MainActivity extends AppCompatActivity {

  注入控件 等价于 findVIewById(R.id.tv_text)

    @ViewInject(R.id.tv_text)
private TextView tvText;
注入数据资源
//id表示资源的id type表示资源的数据类型,String,demens.color,drawable,animation...
    @ResInject(id = R.string.hello,type = ResType.String)
private String hello;

注入点击事件:方法名可以任意,但是参数必须与原始的参数一致

// 取消了之前使用方法名绑定事件的方式,使用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})

    @OnClick(R.id.btn01)
public void onButtonClick(View view){
Toast.makeText(this,"点击了btn01",Toast.LENGTH_SHORT).show(); }

!!!使用碎片可以进行碎片注入,注入碎片后方可对其中的控件进行注入操作

在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和事件
...
}

BitmapUtils使用方法

首先我们需要创建一个BitmapUtils对象,一个活动只需要创建一个,因此我们设置在MyApplication中,注意需要在清单文件中注册

public class MyApplication extends Application {
private static BitmapUtils bitmapUtils;
@Override
public void onCreate() {
super.onCreate();
//创建对象
bitmapUtils = new BitmapUtils(getApplicationContext());
}
public static BitmapUtils getBitmapUtils(){
return bitmapUtils;
}
}

这里将该对象进行了封装,活动只需要调用MyApplication的getBitmapUtils方法就可以得到该对象了,主活动的onCreate方法中注入actiivity和得到bitmapUtils对象

        ViewUtils.inject(this);//注入view和事件
bitmapUtils = MyApplication.getBitmapUtils();

加载本地图片(路径以/开头, 绝对路径):需要加入权限(android.permission.WRITE_EXTERNAL_STORAGE)

    @OnClick(R.id.btn_file)
public void onClickSDCard(View view){
//参数一:要设置图片的图片控件
bitmapUtils.display(image,"/mnt/sdcard/img/a.jpg");
加载assets中的图片(路径以assets开头)
    @OnClick(R.id.btn_assert)
public void onClickAssets(View view){
bitmapUtils.display(image,"assets/a.jpg");
}

加载网络图片:(需要加入权限android.permission.INTERNET)

显示图片到指定控件,如果是ImageView,会调用setImageBitmap(bitmap);其他控件使用setBackgroundDrawable(drawable)
方式一:
container - 控件View
uri - 本地文件完整路径,assets文件路径(assets/xxx),或者URL地址
itmapUtils.display(image,"http://p1.so.qhmsg.com/t01e63fec232667f916.jpg");

方式二:

  参数:
container - 控件View
uri - 本地文件完整路径,assets文件路径(assets/xxx),或者URL地址
displayConfig - 图片显示配置项BitmapDisplayConfig
 BitmapDisplayConfig bitmapDisplayConfig = new BitmapDisplayConfig();//创建图片显示配置项对象
//设置最大尺寸
bitmapDisplayConfig.setBitmapMaxSize(new BitmapSize(200,200));
//设置动画
ScaleAnimation scaleAnimation = new ScaleAnimation(0, 1, 0, 1, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
scaleAnimation.setDuration(2000);
scaleAnimation.setRepeatCount(1);
scaleAnimation.setFillAfter(true); bitmapDisplayConfig.setAnimation(scaleAnimation);
// bitmapUtils.display(image,"http://p1.so.qhmsg.com/t01e63fec232667f916.jpg",bitmapDisplayConfig);

方式三:

    //该方法设置动画效果没用
 参数:
container - 控件View
uri - 本地文件完整路径,assets文件路径(assets/xxx),或者URL地址
callBack - 图片加载回调接口BitmapLoadCallBack*/
bitmapUtils.display(image, "http://p1.so.qhmsg.com/t01e63fec232667f916.jpg", new BitmapLoadCallBack<ImageView>() {
//加载图片回调监听
@Override
public void onLoadCompleted(ImageView imageView, String s, Bitmap bitmap, BitmapDisplayConfig bitmapDisplayConfig, BitmapLoadFrom bitmapLoadFrom) {
//设置回调后的图片
imageView.setImageBitmap(bitmap);
}
//加载失败
@Override
public void onLoadFailed(ImageView imageView, String s, Drawable drawable) { }
});

方式四:

 //该方法设置动画效果没用

  参数:container - 控件View

uri - 本地文件完整路径,assets文件路径(assets/xxx),或者URL地址

  displayConfig - 图片显示配置项BitmapDisplayConfig

 callBack - 图片加载回调接口BitmapLoadCallBack
bitmapUtils.display(image, "http://p1.so.qhmsg.com/t01e63fec232667f916.jpg", bitmapDisplayConfig, new BitmapLoadCallBack<ImageView>() {
@Override
public void onLoadCompleted(ImageView imageView, String s, Bitmap bitmap, BitmapDisplayConfig bitmapDisplayConfig, BitmapLoadFrom bitmapLoadFrom) {
imageView.setImageBitmap(bitmap);
} @Override
public void onLoadFailed(ImageView imageView, String s, Drawable drawable) { }
});

DBUtils使用方法

创建数据库:

  参数:
context - android.content.Context
dbDir - 数据库文件存储路径
dbName - 数据库文件名
dbVersion - 数据库版本号
dbUpgradeListener - 数据库版本升级通知接口
返回:
DbUtils实例DbUtils
 dbUtils = DbUtils.create(this, getCacheDir().getAbsolutePath(), "dbUtils.db",1, this)

这里由于该类实现了DbUtils.DbUpgradeListener,实现了其中的方法,所以最后一个参数传入this

实现的方法

 /**
* 更新数据库
* @param dbUtils
* @param i 旧版本
* @param i1 新版本
*/
@Override
public void onUpgrade(DbUtils dbUtils, int i, int i1) {
Log.i("tag","onUpgrade--i--"+i+"--i1--"+i1);
dbUtils = DbUtils.create(this, getCacheDir().getAbsolutePath(), "dbUtils.db",2, this);
}

创建表:

 * 创建表
* @param v
*/
@OnClick(R.id.btn_createTab)
public void onCreateTable(View v){ //创建数据库表,当表不存在时
//entityType - 实体类类型Class
try {
dbUtils.createTableIfNotExist(Student.class);

简单的增删改查方法:

增:

保存实体到DB(insert)
根据实体类注解,自动创建表;
只持久化基本数据类型、java.lang.*等,不能处理的类型自动忽略;
对静态属性、添加忽略注解属性自动忽略。
插入一条数据:
    Student student = new Student();
student.setAge(19);
student.setName("张三");
student.setSex("男");
//插入一条数据
dbUtils.save(student);

插入多条数据:

            //插入多条数据,当有一条数据出错时,后面的数据不会再进行插入操作
List<Student>dataList = new ArrayList<>();
for (int i = 0; i < 20; i++) {
Student student = new Student();
student.setName("alice"+(i+1));
student.setAge((i+19));
if(i % 2 == 0) {
student.setSex("男");
}else{
student.setSex("女");
}
dataList.add(student);
}
dbUtils.saveAll(dataList);

删:

     //删除id>85,age>22的数据
dbUtils.delete(Student.class,WhereBuilder.b("_id",">","85").and("age",">","22"));

改:

            //更新_id>40的数据为贝塔,1000,女
List<Student> list = dbUtils.findAll(Selector.from(Student.class).where(WhereBuilder.b("_id",">","40")));
for (int i = 0; i < list.size(); i++) {
Student s = list.get(i);
s.setAge(1000); s.setName("贝塔"); s.setSex("女");
// updateColumnNames为空时,更新所有字段的值
//entity - 实体类实例 updateColumnNames -String..可变参数 需要更新的字段名,
dbUtils.update(s,"age","name","sex");
    //更新所有_id<10的名字
    dbUtils.update(s,WhereBuilder.b("_id","<","10"),"name");
 

查:

      //查询所有数据
List<Student> list = dbUtils.findAll(Student.class);
  //查询1
List<DbModel> dbModelAll = dbUtils.findDbModelAll(DbModelSelector.
from(Student.class). //表示从那个表查询
select("_id", "name", "sex", "age"). //表示查询的字段
where("age", "<", "22")); //表示查询条件*/
  //查询所有_id<10的数据
// List<Student> list = dbUtils.findAll(Selector.from(Student.class).where("_id", "<", "10"));

实体类:

/**
* 创建表
*
*/
//指定表名
@Table(name = "Student")
public class Student {
//指定列名
@Column(column = "_id")
//指定是主键
@Id(column = "_id")
private int _id; @Column(column = "name")
private String name; @Column(column = "age")
//限制条件 年龄大于18
@Check("age > 18 ")
private int age; //性别必须为男或者女
@Column(column = "sex")
@Check("sex in ('男','女')")
private String sex;
public int get_id() {
return _id;
}
public void set_id(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;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}

HttpUtils使用

httpUtils仅仅支持安卓6.0以下应用,因为里面使用的都是HttpClient的网络请求方式,而google公司已经将其弃用.

普通Get方法:

   //声名httputils工具
HttpUtils httpUtils = new HttpUtils();
//发送请求
httpUtils.send(HttpRequest.HttpMethod.GET, pathGet, new RequestCallBack<String>() {
//*请求成功的回调*//*
@Override
public void onSuccess(ResponseInfo<String> responseInfo) {
//获取数据
String string = responseInfo.result;
Log.i("AAA",string);
Log.i("AAA","ThreadName:-" + Thread.currentThread().getName() + "-threadId-" + Thread.currentThread().getId());
}
@Override
public void onFailure(HttpException e, String s) {
}
});
}

post方法:

   HttpUtils httpUtils = new HttpUtils();
//post提交的字段:pageNo=1&pageSize=20&serialIds=2143,3404&v=4.0.0
// String pathPost = "http://mrobot.pcauto.com.cn/v2/cms/channels/1?";
RequestParams requestParams = new RequestParams();
//设置post请求参数
requestParams.addBodyParameter("pageNo", "1");
requestParams.addBodyParameter("pageSize", "20");
requestParams.addBodyParameter("serialIds", "2143,3404");
requestParams.addBodyParameter("v", "4.0.0"); /* com.lidroid.xutils.http.client.HttpRequest.HttpMethod method, 请求类型 Get,Post..
@NotNull java.lang.String url, 网络地址
com.lidroid.xutils.http.RequestParams params, 请求参数
com.lidroid.xutils.http.callback.RequestCallBack<T> callBack 请求成功的回调
httpUtils.send()*/
httpUtils.send(HttpRequest.HttpMethod.POST, pathPost, requestParams, new RequestCallBack<String>() {
@Override
public void onSuccess(ResponseInfo<String> responseInfo) {
Log.i("AAA", "onSuccess: " + responseInfo.result);
} @Override
public void onFailure(HttpException e, String s) {
}
});
}
  • 使用HttpUtils下载文件:(需加入网络权限,写入sd卡的权限)

  • 支持断点续传,随时停止下载任务,开始任务
  • 注意:回调的方法在主线程中执行
@ContentView(R.layout.activity_main)
public class MainActivity extends Activity {
@ViewInject(R.id.tvText)
private TextView tvText;
private String pathApk = "http://down.72g.com/upload/app/201407/201407150923238621.apk";
private ProgressDialog progressDialog;
private HttpHandler<File> httpHandler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//注入activity
ViewUtils.inject(this);
//初始化对话框
initProgressDialog(); }
/*初始化对话框*/
private void initProgressDialog() {
//创建进度条对话框
progressDialog = new ProgressDialog(this);
//设置标题
progressDialog.setTitle("下载文件");
//设置信息
progressDialog.setMessage("玩命下载中...");
//设置显示的格式
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
//设置按钮
progressDialog.setButton(ProgressDialog.BUTTON_NEGATIVE, "暂停",new DialogInterface.OnClickListener(){ @Override
public void onClick(DialogInterface dialog, int which) {
//点击取消正在下载的操作,再次触发点击事件时,会重新创建httpHandler对象,但会从暂停的地方继续下载,从而实现了断点续传的操作
httpHandler.cancel(); }});
}
@OnClick(R.id.btn_download)
public void onClickDownLoadFile(View view){
//声明httpUtils工具
HttpUtils httpUtils = new HttpUtils();
//存储的路径
String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/app3.apk";
    //下载
httpHandler = httpUtils.download(pathApk,//文件地址
            path,//文件下载的目标目录
            true,// 如果目标文件存在,接着未完成的部分继续下载。服务器不支持RANGE时将从新下载。
           true,// 如果从请求返回信息中获取到文件名,下载完成后自动重命名
    new RequestCallBack<File>() {//下载的回调,在主线程中运行
  /*执行下载操作之前调用*/
@Override
public void onStart() {
super.onStart();
//显示对话框
progressDialog.show();
}
/*正在下载的时候调用*/
@Override
public void onLoading(long total, long current, boolean isUploading) {
super.onLoading(total, current, isUploading);
// Log.i("tag", "线程--"+Thread.currentThread().getName());
// Log.i("tag", "current--total--"+current+"--"+total);
//设置进度
progressDialog.setProgress((int)(current*100/total));
}
/*请求成功的时候调用*/
@Override
public void onSuccess(ResponseInfo<File> responseInfo) {
progressDialog.dismiss();
Log.i("tag","下载成功");
//获得下载后的文件
File file = responseInfo.result;
InstallApkUtils.inStallApk(MainActivity.this, file);
}
/*请求失败的时候调用*/
@Override
public void onFailure(HttpException error, String msg) {
Log.i("tag", "下载失败");
progressDialog.dismiss();
}
/*取消的时候调用*/
@Override
public void onCancelled() {
super.onCancelled();
Log.i("tag","取消下载");
}
}); } }

安装apk的工具类:

public static void inStallApk(Context context,File file){
Intent intent = new Intent();
//隐式意图激活安装 apk 的activity
intent.setAction(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
context.startActivity(intent);
}

效果:
反射机制及开源框架xUitls的使用,使用HttpUtils通过断点续传下载文件

上一篇:IE6下出现横向滚动条问题的解决方案


下一篇:[JSON].getObj( keyPath )