XUtils3的使用(Get,Post,斷點下載,上傳文件,數據庫,bitmap的下載與緩存)


網站: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();

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM