<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          xUtilsAndroid 工具包

          聯(lián)合創(chuàng)作 · 2023-09-25 04:51

          ## xUtils3簡(jiǎn)介
          
          xUtils 包含了orm, http(s), image, view注解, 但依然很輕量級(jí)(251K), 并且特性強(qiáng)大, 方便擴(kuò)展.
          
          #### 1. `orm`: 高效穩(wěn)定的orm工具, 使得http接口實(shí)現(xiàn)時(shí)更方便的支持cookie和緩存.
          * 靈活的, 類似linq表達(dá)式的接口.
          * 和greenDao一致的性能.
          
          #### 2. `http(s)`: 基于UrlConnection, Android4.4以后底層為okHttp實(shí)現(xiàn).
          * 請(qǐng)求協(xié)議支持11種謂詞: GET,POST,PUT,PATCH,HEAD,MOVE,COPY,DELETE,OPTIONS,TRACE,CONNECT
          * 支持超大文件(超過(guò)2G)上傳
          * 支持?jǐn)帱c(diǎn)下載(如果服務(wù)端支持Range參數(shù),客戶端自動(dòng)處理斷點(diǎn)下載)
          * 支持cookie(實(shí)現(xiàn)了domain, path, expiry等特性)
          * 支持緩存(實(shí)現(xiàn)了Cache-Control, Last-Modified, ETag等特性, 緩存內(nèi)容過(guò)多時(shí)使用過(guò)期時(shí)間+LRU雙重機(jī)制清理)
          * 支持異步和同步(可結(jié)合RxJava使用)調(diào)用
          
          #### 3. `image`: 有了`http(s)`及其下載緩存的支持, `image`模塊的實(shí)現(xiàn)相當(dāng)?shù)暮?jiǎn)潔.
          * 支持內(nèi)存緩存, 磁盤(pán)緩存(縮略圖和原圖), 并且支持回收被view持有, 但被MemCache移除的圖片, 減少頁(yè)面回退時(shí)的閃爍.
          * 支持在ListView滑動(dòng)時(shí), 自動(dòng)停止被回收復(fù)用的item對(duì)應(yīng)的下載任務(wù)(再次下載時(shí)斷點(diǎn)續(xù)傳)
          * 支持webp, gif(部分比較老的系統(tǒng)只展示靜態(tài)圖)
          * 支持圓角, 圓形, 方形等裁剪, 支持自動(dòng)旋轉(zhuǎn)...
          
          #### 4. `view注解`: view注解模塊僅僅400多行代碼卻靈活的支持了各種View注入和事件綁定.
          * 事件注解支持且不受混淆影響...
          * 支持綁定擁有多個(gè)方法的listener
          
          #### 使用Gradle構(gòu)建時(shí)添加以下依賴即可:
          ```javascript
          implementation 'org.xutils:xutils:3.9.0'
          ```
          
          #### 混淆配置參考示例項(xiàng)目sample的配置
          [這里可以下載aar文件](http://dl.bintray.com/wyouflf/maven/org/xutils/xutils/)
          
          
          ### 常見(jiàn)問(wèn)題:
          1. 更好的管理圖片緩存: https://github.com/wyouflf/xUtils3/issues/149
          2. Cookie的使用: https://github.com/wyouflf/xUtils3/issues/125
          3. 關(guān)于query參數(shù)? http請(qǐng)求可以通過(guò) header, url, body(請(qǐng)求體)傳參; query參數(shù)是url中問(wèn)號(hào)(?)后面的參數(shù).
          4. 關(guān)于body參數(shù)? body參數(shù)只有PUT, POST, PATCH, DELETE(老版本RFC2616文檔沒(méi)有明確指出它是否支持, 所以暫時(shí)支持)請(qǐng)求支持.
          5. 自定義Http參數(shù)對(duì)象和結(jié)果解析: https://github.com/wyouflf/xUtils3/issues/191
          6. 設(shè)置了http超時(shí)時(shí)間為5s但任然等待15s左右: GET請(qǐng)求失敗后默認(rèn)會(huì)重試2次, 可以通過(guò)setMaxRetryCount(0)來(lái)防止請(qǐng)求自動(dòng)重試.
          7. @Event注解同一個(gè)id子類的事件會(huì)覆蓋父類, onClickListener和onItemClickListener默認(rèn)屏蔽了雙擊這種手機(jī)上不常用操作, 如需要雙擊支持可以自己setOnClickListener.
          
          #### 使用前配置
          ##### 需要的權(quán)限
          ```xml
          <uses-permission android:name="android.permission.INTERNET" />
          <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><!-- 可選 -->
          ```
          ##### 初始化
          ```java
          // 在application的onCreate中初始化
          @Override
          public void onCreate() {
              super.onCreate();
              x.Ext.init(this);
              x.Ext.setDebug(BuildConfig.DEBUG); // 是否輸出debug日志, 開(kāi)啟debug會(huì)影響性能.
              ...
          }
          ```
          
          ### 使用@Event事件注解(@ContentView, @ViewInject等更多示例參考sample項(xiàng)目)
          ```java
          /**
           * 1. 方法必須私有限定,
           * 2. 方法參數(shù)形式必須和type對(duì)應(yīng)的Listener接口一致.
           * 3. 注解參數(shù)value支持?jǐn)?shù)組: value={id1, id2, id3}
           * 4. 其它參數(shù)說(shuō)明見(jiàn){@link org.xutils.event.annotation.Event}類的說(shuō)明.
           **/
          @Event(value = R.id.btn_test1,
                  type = View.OnClickListener.class/*可選參數(shù), 默認(rèn)是View.OnClickListener.class*/)
          private void onTest1Click(View view) {
          ...
          }
          ```
          
          ### 使用數(shù)據(jù)庫(kù)(更多示例參考sample項(xiàng)目)
          ```java
          Parent test = db.selector(Parent.class)
                              .where("id", "in", new int[]{1, 3, 6})
                              .or("age", "<", 29)
                              .findFirst();
          long count = db.selector(Parent.class)
                              .where("name", "LIKE", "w%")
                              .and("age", ">", 32)
                              .count();
          List<Parent> testList = db.selector(Parent.class)
                              .where("id", "between", new String[]{"1", "5"})
                              .findAll();
          List<DbModel> list = db.selector(Child.class)
                              .where("age", "<", 18)
                              .groupBy("parentId")
                              .having(WhereBuilder.b("COUNT(parentId)", ">", 1))
                              .select("parentId, COUNT(parentId) as childNum")
                              .findAll();
          ```
          
          ### 訪問(wèn)網(wǎng)絡(luò)(更多示例參考sample項(xiàng)目)
          #### 如果你只需要一個(gè)簡(jiǎn)單的網(wǎng)絡(luò)請(qǐng)求:
          ```java
          @Event(value = R.id.btn_test2)
          private void onTest2Click(View view) {
              RequestParams params = new RequestParams("https://www.baidu.com/s");
              // params.setSslSocketFactory(...); // 如果需要自定義SSL
              params.addQueryStringParameter("wd", "xUtils");
              x.http().get(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) {
                      Toast.makeText(x.app(), ex.getMessage(), Toast.LENGTH_LONG).show();
                  }
          
                  @Override
                  public void onCancelled(CancelledException cex) {
                      Toast.makeText(x.app(), "cancelled", Toast.LENGTH_LONG).show();
                  }
          
                  @Override
                  public void onFinished() {
          
                  }
              });
          }
          ````
          #### json或protobuf類型請(qǐng)求的處理
          ```java
          /**
           * 自定義實(shí)體參數(shù)類請(qǐng)參考:
           * 請(qǐng)求注解 {@link org.xutils.http.annotation.HttpRequest}
           * 請(qǐng)求注解處理模板接口 {@link org.xutils.http.app.ParamsBuilder}
           *
           * 需要自定義類型作為callback的泛型時(shí), 參考:
           * 響應(yīng)注解 {@link org.xutils.http.annotation.HttpResponse}
           * 響應(yīng)注解處理模板接口 {@link org.xutils.http.app.ResponseParser}
           *
           * 示例: 查看 org.xutils.sample.http 包里的代碼
           */
          JsonDemoParams params = new JsonDemoParams();
          params.wd = "xUtils";
          // 有上傳文件時(shí)使用multipart表單, 否則上傳原始文件流.
          // params.setMultipart(true);
          // 上傳文件方式 1
          // params.uploadFile = new File("/sdcard/test.txt");
          // 上傳文件方式 2
          // params.addBodyParameter("uploadFile", new File("/sdcard/test.txt"));
          Callback.Cancelable cancelable
                 = x.http().get(params,
                 /**
                 * 1. callback的泛型:
                 * callback參數(shù)默認(rèn)支持的泛型類型參見(jiàn){@link org.xutils.http.loader.LoaderFactory},
                 * 例如: 指定泛型為File則可實(shí)現(xiàn)文件下載, 使用params.setSaveFilePath(path)指定文件保存的全路徑, 默認(rèn)支持?jǐn)帱c(diǎn)續(xù)傳(采用了文件鎖防止多線程/進(jìn)程修改文件,及文件末端校驗(yàn)續(xù)傳文件的一致性).
                 * 
                 * 自定義callback的泛型支持方案1, 自定義某一Class的轉(zhuǎn)換(不夠靈活): 
                 * 結(jié)合PrepareCallback的兩個(gè)泛型參數(shù), 第一個(gè)泛型參數(shù)類型使用LoaderFactory已經(jīng)支持的, 第二個(gè)泛型參數(shù)作為最終輸出, 需要在prepare方法中自己實(shí)現(xiàn).
                 * 一個(gè)稍復(fù)雜的例子可以參考{@link org.xutils.image.ImageLoader}
                 *
                 * 自定義callback的泛型支持方案2, 自定義一類數(shù)據(jù)的自動(dòng)轉(zhuǎn)化: 
                 * 將注解@HttpResponse加到自定義返回值類型上, 實(shí)現(xiàn)自定義ResponseParser接口來(lái)統(tǒng)一轉(zhuǎn)換.
                 * 如果返回值是json/xml/protobuf等數(shù)據(jù)格式, 那么利用第三方的json/xml/protobuf等工具將十分容易定義自己的ResponseParser.
                 * 如示例代碼{@link org.xutils.sample.http.JsonDemoResponse}, 可直接使用JsonDemoResponse作為callback的泛型.
                 *
                 * 2. callback的組合:
                 * 可以用基類或接口組合個(gè)種類的Callback, 見(jiàn){@link org.xutils.common.Callback}.
                 * 例如:
                 * a. 組合使用CacheCallback將使請(qǐng)求檢測(cè)緩存或?qū)⒔Y(jié)果存入緩存(僅GET和POST請(qǐng)求生效).
                 * b. 組合使用PrepareCallback的prepare方法將為callback提供一次后臺(tái)執(zhí)行耗時(shí)任務(wù)的機(jī)會(huì), 然后將結(jié)果給onCache或onSuccess.
                 * c. 組合使用ProgressCallback將提供進(jìn)度回調(diào).
                 * 可參考{@link org.xutils.image.ImageLoader} 或 示例代碼中的 {@link org.xutils.sample.download.DownloadCallback}
                 *
                 * 3. 請(qǐng)求過(guò)程攔截或記錄日志: 參考 {@link org.xutils.http.app.RequestTracker}
                 *
                 * 4. 請(qǐng)求Header獲取: 參考 {@link org.xutils.sample.http.JsonResponseParser} 或 {@link org.xutils.http.app.RequestInterceptListener}
                 *
                 * 5. 其他(線程池, 超時(shí), 重定向, 重試, 代理等): 參考 {@link org.xutils.http.RequestParams}
                 *
                 **/
                 new Callback.CommonCallback<JsonDemoResponse>() {
                     @Override
                     public void onSuccess(JsonDemoResponse result) {
                         Toast.makeText(x.app(), result.toString(), Toast.LENGTH_LONG).show();
                     }
          
                     @Override
                     public void onError(Throwable ex, boolean isOnCallback) {
                         //Toast.makeText(x.app(), ex.getMessage(), Toast.LENGTH_LONG).show();
                         if (ex instanceof HttpException) { // 網(wǎng)絡(luò)錯(cuò)誤
                             HttpException httpEx = (HttpException) ex;
                             int responseCode = httpEx.getCode();
                             String responseMsg = httpEx.getMessage();
                             String errorResult = httpEx.getResult();
                             // ...
                         } else { // 其他錯(cuò)誤
                             // ...
                         }
                         Toast.makeText(x.app(), ex.getMessage(), Toast.LENGTH_LONG).show();
                     }
          
                     @Override
                     public void onCancelled(CancelledException cex) {
                         Toast.makeText(x.app(), "cancelled", Toast.LENGTH_LONG).show();
                     }
          
                     @Override
                     public void onFinished() {
          
                     }
                 });
          
          // cancelable.cancel(); // 取消請(qǐng)求
          ```
          #### 帶有緩存的請(qǐng)求示例:
          ```java
          JsonDemoParams params = new JsonDemoParams();
          params.wd = "xUtils";
          // 默認(rèn)緩存存活時(shí)間, 單位:毫秒.(如果服務(wù)沒(méi)有返回有效的max-age或Expires)
          params.setCacheMaxAge(1000 * 60);
          Callback.Cancelable cancelable
                 // 使用CacheCallback, xUtils將為該請(qǐng)求緩存數(shù)據(jù).
                = x.http().get(params, new Callback.CacheCallback<JsonDemoResponse>() {
          
             private boolean hasError = false;
             private String result = null;
          
             @Override
             public boolean onCache(JsonDemoResponse result) {
                // 得到緩存數(shù)據(jù), 緩存過(guò)期后不會(huì)進(jìn)入這個(gè)方法.
                // 如果服務(wù)端沒(méi)有返回過(guò)期時(shí)間, 參考params.setCacheMaxAge(maxAge)方法.
                  //
                  // * 客戶端會(huì)根據(jù)服務(wù)端返回的 header 中 max-age 或 expires 來(lái)確定本地緩存是否給 onCache 方法.
                  //   如果服務(wù)端沒(méi)有返回 max-age 或 expires, 那么緩存將一直保存, 除非這里自己定義了返回false的
                  //   邏輯, 那么xUtils將請(qǐng)求新數(shù)據(jù), 來(lái)覆蓋它.
                  //
                  // * 如果信任該緩存返回 true, 將不再請(qǐng)求網(wǎng)絡(luò);
                  //   返回 false 繼續(xù)請(qǐng)求網(wǎng)絡(luò), 但會(huì)在請(qǐng)求頭中加上ETag, Last-Modified等信息,
                  //   如果服務(wù)端返回304, 則表示數(shù)據(jù)沒(méi)有更新, 不繼續(xù)加載數(shù)據(jù).
                  //
                  this.result = result;
                  return false; // true: 信任緩存數(shù)據(jù), 不在發(fā)起網(wǎng)絡(luò)請(qǐng)求; false不信任緩存數(shù)據(jù).
             }
          
             @Override
             public void onSuccess(JsonDemoResponse result) {
                // 注意: 如果服務(wù)返回304 或 onCache 選擇了信任緩存, 這時(shí)result為null.
                  if (result != null) {
                    this.result = result;
                }
             }
          
             @Override
             public void onError(Throwable ex, boolean isOnCallback) {
                hasError = true;
                Toast.makeText(x.app(), ex.getMessage(), Toast.LENGTH_LONG).show();
                if (ex instanceof HttpException) { // 網(wǎng)絡(luò)錯(cuò)誤
                   HttpException httpEx = (HttpException) ex;
                   int responseCode = httpEx.getCode();
                   String responseMsg = httpEx.getMessage();
                   String errorResult = httpEx.getResult();
                   // ...
                } else { // 其他錯(cuò)誤
                   // ...
                }
             }
          
             @Override
             public void onCancelled(CancelledException cex) {
                Toast.makeText(x.app(), "cancelled", Toast.LENGTH_LONG).show();
             }
          
             @Override
             public void onFinished() {
                if (!hasError && result != null) {
                   // 成功獲取數(shù)據(jù)
                   Toast.makeText(x.app(), result, Toast.LENGTH_LONG).show();
                }
             }
          });
          ```
          
          ### 綁定圖片(更多示例參考sample項(xiàng)目)
          ```java
          x.image().bind(imageView, url, imageOptions);
          
          // assets file
          x.image().bind(imageView, "assets://test.gif", imageOptions);
          
          // resources file
          x.image().bind(imageView, "res://" + R.minimap.test, imageOptions);
          
          // local file
          x.image().bind(imageView, new File("/sdcard/test.gif").toURI().toString(), imageOptions);
          x.image().bind(imageView, "/sdcard/test.gif", imageOptions);
          x.image().bind(imageView, "file:///sdcard/test.gif", imageOptions);
          x.image().bind(imageView, "file:/sdcard/test.gif", imageOptions);
          
          x.image().bind(imageView, url, imageOptions, new Callback.CommonCallback<Drawable>() {...});
          x.image().loadDrawable(url, imageOptions, new Callback.CommonCallback<Drawable>() {...});
          // 用來(lái)獲取緩存文件
          x.image().loadFile(url, imageOptions, new Callback.CommonCallback<File>() {...});
          ```
          
          瀏覽 9
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          編輯 分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          編輯 分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  毛片操逼 | 蜜乳一区二区三区 | 国产黄色性爱视频 | 国产又粗又长的视频 | 日韩尤物在线播放 |