xutils3 断点续传介绍

转自:http://www.cnblogs.com/tangs/articles/5920643.html

网站:https://github.com/wyouflf/xUtils3  (里面有aar文件的下载地址)

  • xUtils3变化较多所以建立了新的项目不在旧版(github.com/wyouflf/xUtils)上继续维护, 相对于旧版本:
    1. HTTP实现替换HttpClient为UrlConnection, 自动解析回调泛型, 更安全的断点续传策略.
    2. 支持标准的Cookie策略, 区分domain, path...
    3. 事件注解去除不常用的功能, 提高性能.
    4. 数据库api简化提高性能, 达到和greenDao一致的性能.
    5. 图片绑定支持gif(受系统兼容性影响, 部分gif文件只能静态显示), webp; 支持圆角, 圆形, 方形等裁剪, 支持自动旋转..

也正是因为安卓6.0不能使用HttpClient了,所以xUtils2就有影响了,因为内部很多都是使用的HttpClient

将xUtils3.0导入项目:

使用Gradle构建时添加一下依赖即可:

compile 'org.xutils:xutils:3.3.36'

使用Eclipse构建时操作步骤如下:  (aar文件下载地址:  http://dl.bintray.com/wyouflf/maven/org/xutils/xutils/ )

    1. 下载aar文件并使用然后用zip解压, 取出jar包和so文件.  aar文件在上面给的github网站里有说到
      这里写图片描述
    2. 将xutils.jar 以及armeabi目录下的.so文件添加到工程的libs中即可。

所需权限:

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

在application的onCreate中初始化:   切记在清单文件加name属性 android:name=".MyApplication"

复制代码
public class MyApplication extends Application {
    @Override
    publicvoidonCreate() {
        super.onCreate();
        x.Ext.init(this);//Xutils初始化,这一步之后, 我们就可以在任何地方使用x.app()来获取Application的实例了.
        x.Ext.setDebug(true); // 是否输出debug日志
    }
}
复制代码

注解的使用可以参考: http://blog.csdn.net/qq_25508039/article/details/50902620

 利用XUtils3对数据库的操作,以及注解的使用,与Xutils2有很大的区别:

复制代码
import org.xutils.db.annotation.Column;
import org.xutils.db.annotation.Table;

/**
 * 数据库表的实体类
 */
@Table(name = "student") //确定表名
public class Student {

    //必须要有无参构造,否则创建表不成功
    public Student() {
    }

    @Column(name = "_id", isId = true, autoGen = true)//isId为true,代表为主键,autoGen为true代表自增
    public int _id;

    @Column(name = "name")//设置为列名
    public String name;// 姓名

    @Column(name = "age")
    public int age;// 年龄

    @Column(name = "sex")
    public 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;
    }
}
复制代码

具体的操作:

复制代码
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;

import org.xutils.DbManager;
import org.xutils.db.sqlite.SqlInfo;
import org.xutils.db.sqlite.WhereBuilder;
import org.xutils.db.table.DbModel;
import org.xutils.db.table.TableEntity;
import org.xutils.ex.DbException;
import org.xutils.view.annotation.ContentView;
import org.xutils.view.annotation.Event;
import org.xutils.x;

import java.util.ArrayList;
import java.util.List;

/**
 * XUtils3对数据库的操作
 */
@ContentView(R.layout.activity_main) //加载的xml文件
public class MainActivity extends AppCompatActivity {

    /**
     * 数据库的配置信息对象
     */
    private DbManager.DaoConfig daoConfig;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //setContentView(R.layout.activity_main);
        x.view().inject(this);//绑定注解
        //初始化数据库配置信息
        initDaoConfig();

    }

    @Event(value = {R.id.add ,R.id.query,R.id.updata,R.id.delete})
    private void btnOnClick(View view){ //必须是private单击事件才有效
        switch (view.getId()){
            case R.id.add:
                addData();
                break;
            case R.id.query:
                onQuertyData();
                break;
            case R.id.updata:
                onUPdataData();
                break;
            case R.id.delete:
                deleteData();
                break;
        }
    }

    /**
     * 增加数据,插入数据库操作的时候会判断是否存在这张表,如果不存在就会去创建,所以不需要手动去创建表了
     */
    public void addData(){
        try {
            //根据配置信息获取操作数据的db对象
            DbManager db = x.getDb(daoConfig);
            List<Student> list = new ArrayList<Student>();
            for (int i = 0; i < 10; i++) {
                Student stu = new Student();
                stu.setAge(10+i);
                stu.setName("学生"+i);
                stu.setSex(i % 2 == 0? "男":"女");
                list.add(stu);
                //db.save(stu);//插入一条数据
            }
            db.save(list);//保存实体类或实体类的List到数据库
            //db.replace(list);保存或更新实体类或实体类的List到数据库, 根据id和其他唯一索引判断数据是否存在
            //db.saveOrUpdate(list);保存或更新实体类或实体类的List到数据库, 根据id对应的数据是否存在.
            //db.saveBindingId(list);保存实体类或实体类的List到数据库,如果该类型的id是自动生成的, 则保存完后会给id赋值.
            /**
             * 1.如果在你建表的时候你的主键设置成自增长,那么你在插入数据的时候直接调replace方法就可以了,
             *   但是saveOrUpdate只能达到插入的效果,达不到更新原有数据的效果.
             * 2.如果在你建表的时候你的主键设置成不是自增长,replace方法当然可以插入,saveOrUpdate方法既可以插入也可以达到更新的效果
             */
        } catch (DbException e) {
            e.printStackTrace();
        }
    }

    /**
     * 查询数据
     */
    public void onQuertyData(){
        try {
            DbManager db = x.getDb(daoConfig);
            Student student = db.findById(Student.class, 2);//根据主键来查找student表里的数据
            Student first = db.findFirst(Student.class);//返回当前表的第一条数据
            Log.i("tag", "第一条数据:"+first);
            //查询所有数据
            List<Student> all = db.findAll(Student.class);
            Log.i("tag", "所有数据:"+all.toString());
            //按条件查找,查询年龄大于15的
            List<DbModel> dbModelAll = db.findDbModelAll(new SqlInfo("select * from student where age > 15"));
            for (int i = 0; i < dbModelAll.size() ; i++) {
                String name = dbModelAll.get(i).getString("name");
                String age = dbModelAll.get(i).getString("age");
                String sex = dbModelAll.get(i).getString("sex");
                Log.i("tag", "查询的数据: name="+name+",age="+age+",sex="+sex);
            }
            //第二种条件查找
            List<Student> all1 = db.selector(Student.class).where("age", ">", 14).and("age", "<", 16).findAll();
            //第三种
            List<Student> all2 = db.selector(Student.class).expr("age>14 and age<17").findAll();
            Log.i("tag", "第二种:"+all1.toString());
        } catch (DbException e) {
            e.printStackTrace();
        }
    }

    /**
     * 更新数据
     */
    public void onUPdataData(){
        try {
            DbManager db = x.getDb(daoConfig);
            //先找到要更新的数据,再设置值,然后更新,当然你也可以使用上面查询数据的方式
            Student stu3 = db.findById(Student.class, 3);//找到主键为3的值
            stu3.setAge(50);
            db.update(stu3,"age");//更新stu3列名为age的数据
        } catch (DbException e) {
            e.printStackTrace();
        }
    }

    /**
     * 删除数据
     */
    public void deleteData(){
        try {
            //第一种,根据主键来删除
            DbManager db = x.getDb(daoConfig);
            db.deleteById(Student.class,5);//删除主键为5的值

            //第二种方法,找到符合条件的第一条数据  .findAll()就是找所有符合条件的了
            Student student = db.selector(Student.class).where("name", "=", "学生11").findFirst();
            db.delete(student);//先找到,再删除 ,需要判断为不为空

            //第三种,删除那name=学生9 且 sex=女 的数据
            db.delete(Student.class, WhereBuilder.b("name","=" ,"学生9").and("sex","=","女"));

            //第四种,删除所有数据,但是表还在
            db.delete(Student.class);

            //db.dropTable(Student.class);删除表
            //db.dropDb();删除数据库

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

    /**
     * 初始化获取数据库的配置信息
     */
    public void initDaoConfig(){
        daoConfig = new DbManager.DaoConfig()
                .setDbName("my.db")  //设置数据库名称
                .setDbVersion(1)  //设置数据库版本
                .setDbDir(getCacheDir().getAbsoluteFile()) //设置数据库保存的路径
                .setAllowTransaction(true) //设置允许开启事务
                .setDbUpgradeListener(new DbManager.DbUpgradeListener() {
                    @Override
                    public void onUpgrade(DbManager db, int oldVersion, int newVersion) {
                        //db.addColumn("表名","需要增加的列名");数据库更新监听
                    }
                })
                .setDbOpenListener(new DbManager.DbOpenListener() {
                    @Override
                    public void onDbOpened(DbManager db) {
                        //开启WAL.对写入加速提示很大
                        db.getDatabase().enableWriteAheadLogging();
                    }
                })
                .setTableCreateListener(new DbManager.TableCreateListener() {
                    @Override
                    public void onTableCreated(DbManager db, TableEntity<?> table) {
                        Log.i("tag", "onTableCreated: 创建了表:"+table.getName());
                    }
                });
    }

}
复制代码

Xutils3的Get与Post请求:

复制代码
 /**
     * Get请求,可以直接在主线程中调用该方法
     */
    public void xUtils3Get(String url){
        //设置网络请求的参数
        RequestParams params = new RequestParams(url);
        //使用的普通回调
        Callback.Cancelable cancelable = x.http().get(params, new Callback.CommonCallback<String>() {
            @Override
            public void onSuccess(String result) {
                Log.i("tag", "请求成功: "+result);
            }

            @Override
            public void onError(Throwable ex, boolean isOnCallback) {
                Log.i("tag", "请求异常");
            }

            @Override
            public void onCancelled(CancelledException cex) {
                Log.i("tag", "取消请求的回调方法");
            }

            @Override
            public void onFinished() {
                Log.i("tag", "请求完成,并不一定是请求成功,断开了连接就会执行该方法");
            }
        });
        //cancelable.cancel();取消请求
    }

    /**
     * Post请求,可以直接在主线程中调用该方法
     */
    public void xUtils3Post(String url){
        //设置网络请求的参数,以及post的字段
        RequestParams params = new RequestParams("http://mrobot.pcauto.com.cn/v2/cms/channels/1?");
        //post提交的字段:pageNo=1&pageSize=20&serialIds=2143,3404&v=4.0.0
        params.addBodyParameter("pageNo","1");
        params.addBodyParameter("pageSize","20");
        params.addBodyParameter("serialIds","2143,3404");
        params.addBodyParameter("v","4.0.0");
        //使用的普通回调
        Callback.Cancelable cancelable = x.http().post(params, new Callback.CommonCallback<String>() {
            @Override
            public void onSuccess(String result) {
                Log.i("tag", "请求成功: "+result);
            }

            @Override
            public void onError(Throwable ex, boolean isOnCallback) {
                Log.i("tag", "请求异常");
            }

            @Override
            public void onCancelled(CancelledException cex) {
                Log.i("tag", "取消请求的回调方法");
            }

            @Override
            public void onFinished() {
                Log.i("tag", "请求完成,并不一定是请求成功,断开了连接就会执行该方法");
            }
        });
        //cancelable.cancel();取消请求
    }
复制代码

使用Xutils3实现断点下载:

复制代码
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;

import org.xutils.common.Callback;
import org.xutils.common.task.PriorityExecutor;
import org.xutils.http.RequestParams;
import org.xutils.view.annotation.ContentView;
import org.xutils.view.annotation.Event;
import org.xutils.x;

import java.io.File;

/**
 * XUtils3实现断点下载
 */
@ContentView(R.layout.activity_main) //加载的xml文件
public class MainActivity extends AppCompatActivity {

    /**
     * 可取消的任务
     */
    private Callback.Cancelable cancelable;
    /**
     * 进度条对话框
     */
    private ProgressDialog progressDialog;

    private String pathApk = "http://down.72g.com/upload/app/201407/201407150923238621.apk";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //setContentView(R.layout.activity_main);
        x.view().inject(this);//绑定注解
        initProgressDialog();
    }

    @Event(R.id.download)
    private void btnOnClick(View view){
        //设置请求参数
        RequestParams params = new RequestParams(pathApk);
        params.setAutoResume(true);//设置是否在下载是自动断点续传
        params.setAutoRename(false);//设置是否根据头信息自动命名文件
        params.setSaveFilePath("/sdcard/xutils/xUtils_1.avi");
        params.setExecutor(new PriorityExecutor(2, true));//自定义线程池,有效的值范围[1, 3], 设置为3时, 可能阻塞图片加载.
        params.setCancelFast(true);//是否可以被立即停止.
        //下面的回调都是在主线程中运行的,这里设置的带进度的回调
        cancelable = x.http().get(params, new Callback.ProgressCallback<File>() {
            @Override
            public void onCancelled(CancelledException arg0) {
                Log.i("tag", "取消"+Thread.currentThread().getName());
            }

            @Override
            public void onError(Throwable arg0, boolean arg1) {
                Log.i("tag", "onError: 失败"+Thread.currentThread().getName());
                progressDialog.dismiss();
            }

            @Override
            public void onFinished() {
                Log.i("tag", "完成,每次取消下载也会执行该方法"+Thread.currentThread().getName());
                progressDialog.dismiss();
            }

            @Override
            public void onSuccess(File arg0) {
                Log.i("tag", "下载成功的时候执行"+Thread.currentThread().getName());
            }

            @Override
            public void onLoading(long total, long current, boolean isDownloading) {
                if (isDownloading) {
                    progressDialog.setProgress((int) (current*100/total));
                    Log.i("tag", "下载中,会不断的进行回调:"+Thread.currentThread().getName());
                }
            }

            @Override
            public void onStarted() {
                Log.i("tag", "开始下载的时候执行"+Thread.currentThread().getName());
                progressDialog.show();
            }

            @Override
            public void onWaiting() {
                Log.i("tag", "等待,在onStarted方法之前执行"+Thread.currentThread().getName());
            }

        });
    }

    /*初始化对话框*/
    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) {
                //点击取消正在下载的操作
                cancelable.cancel();
            }});
    }

}
复制代码

效果图:

 一些其他请求方式:

复制代码
//使用缓存下载
    @Event(R.id.btn)
    private void btnOnClick(View view){
        //设置网络请求的参数
        RequestParams params = new RequestParams("http://m2.qiushibaike.com/article/list/latest?page=1");
        params.setCacheMaxAge(1000 * 15);//设置缓存的时间
        //使用带缓存的回调
        Callback.Cancelable cancelable = x.http().get(params, new Callback.CacheCallback<String>(){

            @Override
            public void onSuccess(String result) {
                Log.i("tag", "请求成功: "+result);
            }

            @Override
            public void onError(Throwable ex, boolean isOnCallback) {

            }

            @Override
            public void onCancelled(CancelledException cex) {

            }

            @Override
            public void onFinished() {

            }

            @Override
            public boolean onCache(String result) {
                //在setCacheMaxAge设置范围(上面设置的是15秒)内,如果再次调用GET请求,
                //返回true:缓存内容被返回,相信本地缓存,返回false:缓存内容被返回,不相信本地缓存,仍然会请求网络
                Log.i("tag","缓存的:"+result);
                return true;
            }
        });
        //cancelable.cancel();取消请求
    }


    /**
     * 上传文件
     */
    private void upload(View v){
        String path="/mnt/sdcard/Download/icon.jpg";
        RequestParams params = new RequestParams("地址");
        params.setMultipart(true);
        params.addBodyParameter("file",new File(path));//设置上传的文件路径
        x.http().post(params, new Callback.CommonCallback<String>() {
            @Override
            public void onSuccess(String result) {
            }
            @Override
            public void onError(Throwable ex, boolean isOnCallback) {
            }
            @Override
            public void onCancelled(CancelledException cex) {
            }
            @Override
            public void onFinished() {
            }
        });
    }
复制代码

 使用XUtils3缓存bitmap图片:

复制代码
 //对图片的操作
    public void operationImg(String url){
        //设置下载的图片参数
        ImageOptions.Builder builder = new ImageOptions.Builder();
        builder.setFadeIn(true);//设置为淡入效果
        //builder.setCircular(true);//设置图片显示为圆形
        builder.setSquare(true);//设置图片显示为正方形
        builder.setCrop(true);//如果ImageView的大小不是定义为wrap_content, 不要crop.
        builder.setSize(200,200);//设置图片的大小
        builder.setImageScaleType(ImageView.ScaleType.CENTER_CROP);//设置图片的缩放模式
        //builder.setFailureDrawableId();设置加载图片失败的图片
        //builder.setLoadingDrawableId();设置加载中的图片
        //builder.setPlaceholderScaleType(ImageView.ScaleType.MATRIX);加载中或错误图片的ScaleType
        //builder.setIgnoreGif(true);设置为忽略Gif图片
        //builder.setParamsBuilder();设置参数,包括线程池,缓存文件名的设置,大小的设置,等等
        builder.setRadius(50);//设置拐角的弧度(四个角的弧度)
        builder.setUseMemCache(false);//设置使用缓存(优先sd卡),默认为true
        ImageOptions options = builder.build();

        //x.image().clearCacheFiles();清除磁盘缓存的文件夹
        //x.image().clearMemCache();清除内部缓存
        //加载本地图片
        //x.image().bind(imageView, new File("/sdcard/test.gif").toURI().toString(), options);
        //x.image().bind(imageView, "/sdcard/test.gif", options);
        //x.image().bind(imageView, "file:///sdcard/test.gif", options);

        //加载网络图片
        //x.image().bind(imageView,url);
        x.image().bind(imageView,url,options);
       /* x.image().bind(imageView, url, options, new Callback.CacheCallback<Drawable>() {
            @Override
            public boolean onCache(Drawable result) {
                return false;
            }

            @Override
            public void onSuccess(Drawable result) {
            }

            @Override
            public void onError(Throwable ex, boolean isOnCallback) {
            }

            @Override
            public void onCancelled(CancelledException cex) {
            }

            @Override
            public void onFinished() {
            }
        });*/
    }
复制代码

 关于缓存的一些参数:

复制代码
 /* // 扩展参数
       关于缓存的信息在 :ImageLoader类中
    private final static String DISK_CACHE_DIR_NAME = "xUtils_img";  //SD卡的缓存名
    private final static Executor EXECUTOR = new PriorityExecutor(10, false);//默认线程数
    private final static int MEM_CACHE_MIN_SIZE = 1024 * 1024 * 4; // 4M  内存缓存最小为4兆  可以自己设置

    private static final int LIMIT_COUNT = 5000; // 限制最多5000条数据
    private static final long LIMIT_SIZE = 1024L * 1024L * 100L; // 限制最多100M文件
private Proxy proxy; // 代理 private boolean useCookie = true; // 是否在请求过程中启用cookie private String cacheDirName; // 缓存文件夹名称 private long cacheSize; // 缓存文件夹大小 private long cacheMaxAge; // 默认缓存存活时间, 单位:毫秒.(如果服务没有返回有效的max-age或Expires) private Executor executor; // 自定义线程池 private Priority priority = Priority.DEFAULT; // 请求优先级 private int connectTimeout = 1000 * 15; // 连接超时时间 private boolean autoResume = true; // 是否在下载是自动断点续传 private boolean autoRename = false; // 是否根据头信息自动命名文件 private int maxRetryCount = 2; // 最大请求错误重试次数 private String saveFilePath; // 下载文件时文件保存的路径和文件名 private boolean cancelFast = false; // 是否可以被立即停止, true: 为请求创建新的线程, 取消时请求线程被立即中断. private int loadingUpdateMaxTimeSpan = 300; // 进度刷新最大间隔时间(ms) private HttpRetryHandler httpRetryHandler; // 自定义HttpRetryHandler private RedirectHandler redirectHandler; // 自定义重定向接口, 默认系统自动重定向. private RequestTracker requestTracker; // 自定义日志记录接口.
*/ //设置参数的使用 builder.setParamsBuilder(new ImageOptions.ParamsBuilder(){ @Override public RequestParams buildParams(RequestParams params, ImageOptions options) { params.setCacheDirName("mySDCache");//设置sd卡上的缓存文件名,默认为xUtils_img long cacheSize = params.getCacheSize(); Log.i("tag", "缓存大小:"+cacheSize/1024); return params; } }); builder.setUseMemCache(true);//设置使用缓存(优先sd卡),默认为true options = builder.build();
复制代码
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值