1. 程式人生 > >Xutils使用詳解(二)

Xutils使用詳解(二)

一、xUtils簡介:

xUtils是基於Afinal開發的目前功能比較完善的一個Android開源框架,官網:https://github.com/wyouflf/xUtils3

  • xUtils 包含了orm, http(s), image, view註解, 但依然很輕量級(246K), 並且特性強大, 方便擴充套件:
  1. 穩定的基石: AbsTask和統一的回撥介面Callback, 任何異常, 即使你的回撥方法實現有異常都會進入onError, 任何情況下onFinished總會讓你知道任務結束了.
  2. 基於高效穩定的orm工具, http模組得以更方便的實現cookie(支援domain, path, expiry等特性)和 快取(支援Cache-Control, Last-Modified, ETag等特性)的支援.
  3. 有了強大的http及其下載快取的支援, image模組的實現相當的簡潔, 並且支援回收被view持有, 但被Mem Cache移除的圖片, 減少頁面回退時的閃爍..
  4. view註解模組僅僅400多行程式碼卻靈活的支援了各種View注入和事件繫結, 包括擁有多了方法的listener的支援.

其他特性:

  • 支援超大檔案(超過2G)上傳
  • 更全面的http請求協議支援(11種謂詞)
  • 擁有更加靈活的ORM, 和greenDao一致的效能
  • 更多的事件註解支援且不受混淆影響...
  • 圖片繫結支援gif(受系統相容性影響, 部分gif檔案只能靜態顯示), webp; 支援圓角, 圓形, 方形等裁剪, 支援自動旋轉...
  • 從3.5.0開始不再包含libwebpbackport.so, 需要在Android4.2以下裝置相容webp的請使用3.4.0版本.

    總的來說。xutils主要有4個模組:註解模組,網路模組,圖片載入模組,資料庫模組。

    二、使用前配置

    1.使用Gradle構建時新增一下依賴即可:

    compile 'org.xutils:xutils:3.4.0'

    或在直接在android studio引入xutils3

2.需要的許可權:

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

三、初始化過程:

新建一個類MyApplication繼承Application:

//初始化
public class MyApplication extends Application {
   public void onCreate() {
    super.onCreate();
    x.Ext.init(this);
    x.Ext.setDebug(true); //是否輸出debug日誌,開啟debug會影響效能。
    }
}

在Manifest檔案中註冊MyApplication

<application

android:name=".MyApp" //註冊MyApplication
...
</application

四、註解模組

註解(Annotation)為我們在程式碼中新增資訊提供了一種形式化的方法,是我們可以在稍後某個時刻方便地使用這些資料(通過 解析註解 來使用這些資料)

[email protected]

載入當前的Activity佈局時 將@ContentView加入到Activity的上方

[email protected]

View註解的作用是代替我們寫了findViewById這行程式碼,一般用於敏捷開發。

[email protected]事件註解

處理控制元件的各種響應事件,需要注意的是:
****
* 1. 方法必須私有限定,
* 2. 方法引數形式必須和type對應的Listener介面一致.
* 3. 註解引數value支援陣列: value={id1, id2, id3}
* 4. type預設View.OnClickListener.class,即可故可以不寫,直接寫@Event(R.id.bt1)如果你想實現其餘點選事件效果,只需要把type值進行修改

例:MainActivity

@ContentView(R.layout.activity_main)//載入佈局xml
public class MainActivity extends AppCompatActivity {
    // view註解要求必須提供id,以使程式碼混淆不受影響。
    // 代價是增加了一次反射,每個控制元件都會。而反射是比較犧牲效能的做法,所以使用View註解算是有利有弊吧。
    @ViewInject(R.id.tv1)
    private TextView tv1;


    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    x.view().inject(this); //繫結註解
    }
    
    //Event事件註解 ,點選bt1後彈出bt1測試
    @Event(value = {R.id.bt1},type = View.OnClickListener.class) 
    //方法需要用private
    private void onTest1click(View view){

    Toast.makeText(this,"bt1測試",Toast.LENGTH_LONG).show();
    }
    //長按事件
    @Event(value = R.id.Long,type = View.OnLongClickListener.class)
    private boolean testOnLongClickListener(View v){
    Toast.makeText(this,"btLong測試",Toast.LENGTH_LONG).show();  
    return true;
    }
}

例:fragment

@ContentView(R.layout.fragment_base)
public class BaseFragment extends Fragment {
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    return x.view().inject(this, inflater, container);
    }
    @Override
    public void onViewCreated(View v, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(v, savedInstanceState);
    }
}

五、網路模組

xUtils3網路模組大大方便了在實際開發中網路模組的開發,xUtils3網路模組大致包括GET請求、POST請求、如何使用其他請求方式、上傳檔案、下載檔案、使用快取等功能。

Get請求

@Event(value = {R.id.bt2},type = View.OnClickListener.class)//註解
private void onTestGet(View view){
    String url ="http://10.203.0.4:8080/login"
    RequestParams params = new RequestParams(url);
    //params.setSslSocketFactory(...); // 設定ssl
    
    params.addQueryStringParameter("username","abc");
    params.addQueryStringParameter("password","123");
    x.http().get(params, new Callback.CommonCallback<String>() {

        public void onSuccess(String result) {
            Toast.makeText(x.app(), result, Toast.LENGTH_LONG).show();
            Log.i("JAVA", "onSuccess result:" + result);

        }
        //請求異常後的回撥方法
        @Override
        public void onError(Throwable ex, boolean isOnCallback) {
        }
        //主動呼叫取消請求的回撥方法
        @Override
        public void onCancelled(CancelledException cex) {
        }
        @Override
        public void onFinished() {

        }
    });
   
}

Post請求

@Event(R.id.bt2)
private void onTestPost(View v) {
    String url = "http://10.203.0.4:8080/login";
    RequestParams params = new RequestParams(url);
    params.addParameter("username", "abc");
    params.addParameter("password", "123");
    x.http().request(HttpMethod.PUT, params, new Callback.CommonCallback<String>() {
        @Override
        public void onSuccess(String result) {
        Toast.makeText(x.app(),result,Toast.LENGTH_LONG).show();
        }
        @Override
        public void onError(Throwable ex, boolean isOnCallback) {
        }
        @Override
        public void onCancelled(CancelledException cex) {
        }
        @Override
        public void onFinished() {
        }
    });
}

使用快取

@Event(R.id.cache)
private void cache(View v) {
RequestParams params = new RequestParams(url);
params.setCacheMaxAge(1000*60); //為請求新增快取時間
Callback.Cancelable cancelable = x.http().get(params, new Callback.CacheCallback<string>() {
    @Override
    public void onSuccess(String result) {
        Log.i("JAVA","onSuccess:"+result);
    }
    @Override
    public void onError(Throwable ex, boolean isOnCallback) {
    }
    @Override
    public void onCancelled(CancelledException cex) {
    }
    @Override
    public void onFinished() {
    }
    //result:快取內容
    @Override
    public boolean onCache(String result) {
        //在setCacheMaxAge設定範圍(上面設定的是60秒)內,如果再次呼叫GET請求,
        //返回true:快取內容被返回,相信本地快取,返回false:快取內容被返回,不相信本地快取,仍然會請求網路
        Log.i("JAVA","cache:"+result);
        return true;
    }
});

上傳檔案

@Event(R.id.upload)
private void upload(View v){
String path="/mnt/sdcard/Download/icon.jpg";
RequestParams params = new RequestParams(url);
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() {
    }
});

下載檔案

@Event(R.id.download)
private void download(View v){
url = "http://10.203.0.4:8080/server/nfctest.apk";
RequestParams params = new RequestParams(url);
//自定義儲存路徑,Environment.getExternalStorageDirectory():SD卡的根目錄
params.setSaveFilePath(Environment.getExternalStorageDirectory()+"/myapp/");
//自動為檔案命名
params.setAutoRename(true);
x.http().post(params, new Callback.ProgressCallback<file>() {
    @Override
    public void onSuccess(File result) {
        //apk下載完成後,呼叫系統的安裝方法
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setDataAndType(Uri.fromFile(result), "application/vnd.android.package-archive");
        startActivity(intent);
    }
    @Override
    public void onError(Throwable ex, boolean isOnCallback) {
    }
    @Override
    public void onCancelled(CancelledException cex) {
    }
    @Override
    public void onFinished() {
    }
    //網路請求之前回調
    @Override
    public void onWaiting() {
    }
    //網路請求開始的時候回撥
    @Override
    public void onStarted() {
    }
    //下載的時候不斷回撥的方法
    @Override
    public void onLoading(long total, long current, boolean isDownloading) {
        //當前進度和檔案總大小
        Log.i("JAVA","current:"+ current +",total:"+total); 
    }
});



六、圖片載入模組

xUtils3圖片模組,重點在於載入圖片的4個bind方法,loadDrawable與loadFIle用法和ImageOptions用法

bind的幾個方法

void bind(ImageView view, String url);

void bind(ImageView view, String url, ImageOptions options);

void bind(ImageView view, String url, Callback.CommonCallback<Drawable> callback);

void bind(ImageView view, String url, ImageOptions options, Callback.CommonCallback<Drawable> callback);

Callback.Cancelable loadDrawable(String url, ImageOptions options, Callback.CommonCallback<Drawable> callback);

Callback.Cancelable loadFile(String url, ImageOptions options, Callback.CacheCallback<File> callback);

1.首先獲取ImageView控制元件

@ViewInject(R.id.iv1)
ImageView image01;
@ViewInject(R.id.iv2)
ImageView image02;
...

2.定義圖片網路地址或本地地址

String[] urls = {
        "http://img4.imgtn.bdimg.com/it/u=3182769660,1810895318&fm=23&gp=0.jpg",
        "http://img2.imgtn.bdimg.com/it/u=1278435851,1308167727&fm=23&gp=0.jpg",
        "http://img2.3lian.com/2014/f4/199/d/6.jpg",
        "http://pic1.win4000.com/wallpaper/4/584b9ea3a511c.jpg"
        ...


};  

3,通過ImageOptions.Builder().set方法設定圖片的屬性 然後通過bind方法載入圖片,顯示圖片方法setImg()如下:

private void setImg() {
    /**
     * 通過ImageOptions.Builder().set方法設定圖片的屬性
     */
    ImageOptions options = new ImageOptions.Builder().setFadeIn(true).build(); //淡入效果
    //ImageOptions.Builder()的一些其他屬性:

    //.setCircular(true) //設定圖片顯示為圓形
    //.setSquare(true) //設定圖片顯示為正方形
    //setCrop(true).setSize(200,200) //設定大小
    //.setAnimation(animation) //設定動畫
    //.setFailureDrawable(Drawable failureDrawable) //設定載入失敗的動畫
    //.setFailureDrawableId(int failureDrawable) //以資源id設定載入失敗的動畫
    //.setLoadingDrawable(Drawable loadingDrawable) //設定載入中的動畫
    //.setLoadingDrawableId(int loadingDrawable) //以資源id設定載入中的動畫
    //.setIgnoreGif(false) //忽略Gif圖片
    //.setParamsBuilder(ParamsBuilder paramsBuilder) //在網路請求中新增一些引數
    //.setRaduis(int raduis) //設定拐角弧度
    //.setUseMemCache(true) //設定使用MemCache,預設true

    /**
     * 載入圖片的4個bind方法
     */
    x.image().bind(image01, urls[0]);

    x.image().bind(image02, urls[1], options);

    x.image().bind(image03, urls[2], options, new Callback.CommonCallback<Drawable>() {
        @Override
        public void onSuccess(Drawable result) {
        }
        @Override
        public void onError(Throwable ex, boolean isOnCallback) {
        }
        @Override
        public void onCancelled(CancelledException cex) {
        }
        @Override
        public void onFinished() {
        }
    });
    x.image().bind(image04, urls[3], options, new Callback.CommonCallback<Drawable>() {
        @Override
        public void onSuccess(Drawable result) {
        }
        @Override
        public void onError(Throwable ex, boolean isOnCallback) {
        }
        @Override
        public void onCancelled(CancelledException cex) {
        }
        @Override
        public void onFinished() {
        }
    });

    /**
     * loadDrawable()方法載入圖片
     */
    Callback.Cancelable cancelable = x.image().loadDrawable(urls[4], options, new Callback.CommonCallback<Drawable>() {
        @Override
        public void onSuccess(Drawable result) {
            image05.setImageDrawable(result);
        }
        @Override
        public void onError(Throwable ex, boolean isOnCallback) {
        }
        @Override
        public void onCancelled(CancelledException cex) {
        }
        @Override
        public void onFinished() {
        }
    });
    //主動取消loadDrawable()方法
    //cancelable.cancel();

    /**
     * loadFile()方法
     * 應用場景:當我們通過bind()或者loadDrawable()方法載入了一張圖片後,
     * 它會儲存到本地檔案中,那當我需要這張圖片時,就可以通過loadFile()方法進行查詢。
     * urls[0]:網路地址
     */
    x.image().loadFile(urls[0],options,new Callback.CacheCallback<File>(){
        @Override
        public boolean onCache(File result) {
            //在這裡可以做圖片另存為等操作
            Log.i("JAVA","file:"+result.getPath()+result.getName());
            return true; //相信本地快取返回true
        }
        @Override
        public void onSuccess(File result) {
            Log.i("JAVA","file");
        }
        @Override
        public void onError(Throwable ex, boolean isOnCallback) {
        }
        @Override
        public void onCancelled(CancelledException cex) {
        }
        @Override
        public void onFinished() {
        }
    });
}

七:資料庫模組的使用

首先進行配置DaoConfig:

DbManager.DaoConfig daoConfig = new DbManager.DaoConfig()
        //設定資料庫名,預設xutils.db
        .setDbName("myapp.db")
        // 不設定dbDir時, 預設儲存在app的私有目錄.
        .setDbDir(new File("/sdcard")) // "sdcard"的寫法並非最佳實踐, 這裡為了簡單, 先這樣寫了.
        .setDbVersion(1)//資料庫版本

        //設定是否允許事務,預設true
        //.setAllowTransaction(true)

        //設定表建立的監聽
        .setTableCreateListener(new DbManager.TableCreateListener(){

            @Override
            public void onTableCreated(DbManager db, TableEntity<?> table) {
                Log.i("JAVA", "onTableCreated:" + table.getName());
            }
        })

        //設定資料庫更新的監聽
        .setDbUpgradeListener(new DbManager.DbUpgradeListener() {
            @Override
            public void onUpgrade(DbManager db, int oldVersion, int newVersion) {

            }
        })
        //設定資料庫開啟的監聽
        .setDbOpenListener(new DbManager.DbOpenListener() {
            @Override
            public void onDbOpened(DbManager db) {
                //開啟資料庫支援多執行緒操作,提升效能
                db.getDatabase().enableWriteAheadLogging();
            }
        });
DbManager db = x.getDb(daoConfig);

然後建立資料庫表Person的實體類:

/**
 * onCreated = "sql" sql:當第一次建立表需要插入資料時候在此寫sql語句例:CREATE UNIQUE INDEX index_name ON person(id,name)
 */
@Table(name ="person",onCreated = "")
public class Person {
    /**
    * name = "id":資料庫表中的一個欄位
    * isId = true:是否是主鍵
    * autoGen = true:是否自動增長
     * property = "NOT NULL":新增約束
    */  
    @Column(name = "id",isId = true,autoGen = true,property = "NOT NULL")
    private int id;
    @Column(name = "c_name")
    private String name;

    public Person(String name) {
        this.name = name;
    }

    //預設的構造方法必須寫出,如果沒有,這張表是建立不成功的
    public Person() {

    }

    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

資料庫的建立與刪除以及資料的增刪改查

資料庫的建立

//資料庫的建立
@Event(R.id.create_db)
private void createDB(View v) throws DbException {
    //用集合向Person表中插入多條資料
    ArrayList<Person> person = new ArrayList<>();
    person.add(new Person("張三"));
    person.add(new Person("李四"));
    person.add(new Person("趙六"));

    //db.save()方法不僅可以插入單個物件,還能插入集合
    db.save(person);
}

資料庫的刪除

//刪除資料庫
@Event(R.id.del_db)
private void delDB(View v) throws DbException {

    db.dropDb();
}

表的刪除

@Event(R.id.del_table)
private void delTable(View v) throws DbException {
    db.dropTable(Person.class);
}

查詢資料

@Event(R.id.select_table)
private void selelctDB(View v) throws DbException {
    //查詢資料庫表中第一條資料
    Person first = db.findFirst(Person.class);
    Log.i("JAVA",first.toString());

    //findAll():查詢所有結果
    List<Person> personAll =db.findAll(Person.class);
    List<String > list = new ArrayList<String>();
    for(int i=0;i<personAll.size();i++){
        list.add(personAll.get(i).toString());
    }
    ArrayAdapter<String> adapter = new ArrayAdapter<String>(MainActivity.this,android.R.layout.simple_list_item_1,list);
    lv1.setAdapter(adapter); 

    //新增查詢條件進行查詢
    WhereBuilder b = WhereBuilder.b();
    b.and("id",">",2); //構造修改的條件
    b.and("id","<",4);
    List<Person> all = db.selector(Person.class).where(b).findAll();
    //第二種寫法:
    List<Person> all2 = db.selector(Person.class).where("id",">",2).and("id","<",4).findAll();
    for(Person person :all){
        Log.i("JAVA",person.toString());
    }
}

修改資料

//修改表中資料
@Event(R.id.update_table)
private void updateTable(View v) throws DbException {
    //第一種寫法:
    Person first = db.findFirst(Person.class);
    first.setName("張三01");
    db.update(first, "c_name"); //c_name:表中的欄位名
    //第二種寫法:
    WhereBuilder b = WhereBuilder.b();
    b.and("id", "=", first.getId()); //構造修改的條件
    KeyValue name = new KeyValue("c_name", "張三02");
    db.update(Person.class, b, name);

    //第三種寫法:
    first.setName("張三修改");
    db.saveOrUpdate(first);
    Toast.makeText(this,"修改成功",Toast.LENGTH_LONG).show();
}

刪除資料

@Event(R.id.del_table_data)
private void delTableData(View v) throws DbException {
    //第一種寫法:
    db.delete(Person.class); //child_info表中資料將被全部刪除
    //第二種寫法,新增刪除條件:
    WhereBuilder b = WhereBuilder.b();
    b.and("id",">",2); //構造修改的條件
    b.and("id","<",4);
    db.delete(Person.class, b);
}

 
 

 

轉載自 部落格園 @favour