乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      Volley介紹

       云中大河 2018-01-04

      Volley是由Google開發(fā)的網(wǎng)絡(luò)請求庫,該庫在2013年Google I / O大會上推出的。 由于在Android SDK中缺少在不干擾用戶體驗的情況下進行網(wǎng)絡(luò)請求的庫,因此開發(fā)了Volley庫。

      在發(fā)布Volley庫之前,Android程序員如果想在客戶端和后臺之間開發(fā)RESTFul系統(tǒng),只能使用類  java.net.HttpURLConnection 和類Apache  org.apache.http.client。

      就算不考慮使用這兩個類時出現(xiàn)的錯誤,除了簡單的HTTP事務(wù)之外,所有事情都必須從頭開始。  如果想緩存圖像或優(yōu)先處理某個請求,則那么這些都必須從頭開始。

      幸運的是,現(xiàn)在有了Volley庫,專門為這些需求而量身打造。

      1.為什么使用Volley?

      避免使用  HttpUrlConnection 和HttpClient

      在較低版本的API(主要是Gingerbread和Froyo)中,  HttpUrlConnectionHttpClient遠未完美。 有一些已知錯誤和bug從未修復(fù)過。 此外,  在最后一次API更新(API 22)中HttpClient被棄用,這意味著它將不再被維護,并且在將來的版本中可能被刪除。

      這些理由足夠你決定切換到更可靠的處理網(wǎng)絡(luò)請求的方式來。

      也要避免  AsyncTask

      自從引入Honeycomb(API 11)系統(tǒng)以來,網(wǎng)絡(luò)操作必須在與主線程不同的單獨線程上執(zhí)行。 這一重大變化導(dǎo)致了大量使用 AsyncTask<Params, Progress, Result> 規(guī)范。

      要使用AsyncTask,首先定義一些準備動作,如在onPreExecute中定義上下文。 然后使用doInBackground 方法執(zhí)行異步任務(wù)。 最后,在onPostExecute中處理結(jié)果。 這是非常簡單的,比實現(xiàn)服務(wù)更容易,并附帶了大量的示例和文檔。

      然而,主要的問題是串行化調(diào)用。 使用AsyncTask類,您無法確定首先進行哪個請求,哪一個必須等待。 一切都是先進先出。

      例如,當您必須加載附加縮略圖列表時,問題就出現(xiàn)了。 當用戶向下滾動并預(yù)期新的結(jié)果時,您不能告訴您的activity,首先加載下一頁的JSON,然后再加載上一個頁的圖像。 這可能會在諸如Facebook或Twitter的應(yīng)用程序中成為嚴重的用戶體驗問題,因為這類APP的新item列表比與其關(guān)聯(lián)的縮略圖更重要。

      Volley旨在通過引入強大的取消API來解決這個問題。 執(zhí)行調(diào)用時不再需要在onPostExecute中檢查activity是否被銷毀。 這有助于避免不必要的 NullPointerException異常。

      它更快了

      前段時間,Google+小組對Android上可用于進行網(wǎng)絡(luò)請求的各種不同方法進行了一系列的性能測試。 當在RESTful應(yīng)用程序中使用時,Volley的得分比其他庫的分數(shù)高出十倍。

      它緩存一切

      Volley自動緩存請求,這是真正的“拯救生命”。 讓我們回到前面給出的例子。 您有一個item列表 - 一個JSON數(shù)組,而且每個item都有一個描述和與之關(guān)聯(lián)的縮略圖。 現(xiàn)在想想如果用戶旋轉(zhuǎn)屏幕會發(fā)生什么:activity被摧毀,列表被再次加載,圖像也是被再次加載。 這將導(dǎo)致資源浪費和糟糕的用戶體驗。

      Volley被證明能解決這個問題。 它記住以前的調(diào)用,并處理activity的銷毀和重建。 它緩存所有的東西,而你不必擔心它。

      小元數(shù)據(jù)操作

      Volley非常適合小調(diào)用,例如JSON對象,列表部分,所選item的詳細信息等。 它為RESTful應(yīng)用程序設(shè)計,因此能給出了最好的結(jié)果。

      然而,當用于流式操作和大量下載時,Volley表現(xiàn)不佳。 與一般思維相反,Volley的名字不是來自運動詞典。 這是作為重復(fù)突發(fā)的調(diào)用,并且分組在一起的。 這就是為什么這個庫不適合這種場合。

      2.Under the Hood

      Volley在三個不同層次上工作,每個層次    都在自己的線程上運行。

      Volley under the hood

      主線程

      在主線程上,與AsyncTask 規(guī)范一致,  只允許觸發(fā)請求并處理其響應(yīng)。 沒有更多了,也沒有更少了。

      主要的后果是您可以忽略doInBackground 方法中發(fā)生的一切  。 Volley自動管理您以前需要關(guān)心的HTTP事務(wù)和捕獲的網(wǎng)絡(luò)錯誤。

      緩存和網(wǎng)絡(luò)線程

      當你向隊列添加一個請求時,會發(fā)生幾件事情。 首先,Volley檢查請求是否可以從緩存獲取服務(wù)。 如果可以,緩存的響應(yīng)被讀取、解析和傳遞。 否則請求被傳遞給網(wǎng)絡(luò)線程。

      在網(wǎng)絡(luò)線程上,一系列線程的循環(huán)不斷工作。 第一個可用的網(wǎng)絡(luò)線程對請求進行排隊、進行HTTP請求、解析響應(yīng)、寫入緩存。 最后,它將解析的響應(yīng)重新發(fā)送回您的主線程,在主線程中的監(jiān)聽器正在等待處理結(jié)果。

      3. 入門

      步驟1:導(dǎo)入Volley

      Volley設(shè)置并不方便。 看起來好像沒有官方的Maven庫可用,這是非常令人困惑的。 你必須依靠官方的源代碼。 您可以通過多種方式之一導(dǎo)入Volley。

      首先,從其存儲庫下載Volley源代碼。 如果你有信心這樣做,這個Git  命令可以為你做所有的工作:

      1
      git clone https://android./platform/frameworks/volley

      直到幾個星期前,您可以使用ant命令行(android update project -p .  然后  ant jar)將所有內(nèi)容包裝起來,并使用簡單的compile files('libs/volley.jar')在Android Studio項目中導(dǎo)入JAR庫  。

      最近,Google已將Volley更新為Android Studio構(gòu)建樣式,從而難以創(chuàng)建獨立的JAR包。 您仍然可以這樣做,但只能使用舊版本的庫。 我個人不鼓勵你使用這個選項,盡管看起來最快。

      您應(yīng)該以經(jīng)典的方式設(shè)置Volley ,即通過將源代碼導(dǎo)入為module。 在Android Studio中,打開項目后,選擇“ 文件”>“新建模塊”,然后選擇“ 導(dǎo)入現(xiàn)有項目”。 選擇剛剛下載源代碼的目錄并確認。 名為Volley的文件夾將顯示在您的項目結(jié)構(gòu)中。 Android Studio自動更新您的  settings.gradle文件以包含Volley模塊,因此您只需要將compile project(':volley')添加到依賴關(guān)系即可完成。

      有第三種方式。 您可以添加build.gradle文件的依賴關(guān)系部分:

      1
      compile 'com.mcxiaoke.volley:library-aar:1.0.15'

      它是官方Google存儲庫的鏡像副本,經(jīng)常同步和更新。 這可能是最簡單和最快速的入門方式了。 但是,請注意,這是一個非官方的 Maven存儲庫,不能保證,也不由Google支持。

      在我看來,投入更多的時間導(dǎo)入官方源代碼還是比較好。 這樣,您可以輕松地跳轉(zhuǎn)到原來的定義和實現(xiàn),以便在有疑問的情況下,您可以隨時依靠官方的Volley源代碼,甚至可以根據(jù)需要進行更改。

      步驟2:使用Volley

      Volley大多數(shù)情況下只用兩個類工作,  RequestQueueRequest。 您首先創(chuàng)建一個  RequestQueue,它管理工作線程并將解析的結(jié)果傳遞回主線程。 然后,給RequestQueue傳遞一個或多個  Request 對象。

      Request構(gòu)造函數(shù)總是把方法類型(GET,POST等)、資源的URL和事件偵聽器作為參數(shù)。 然后,根據(jù)請求的類型,它可能會要求一些更多的變量。

      在下面的例子中,我通過調(diào)用一個Volley方法 Volley.newRequestQueue來創(chuàng)建一個RequestQueue對象。 這將使用Volley定義的默認值設(shè)置RequestQueue對象。

      01
      02
      03
      04
      05
      06
      07
      08
      09
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      String url = "http:///html";
      // Request a string response
      StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
                  new Response.Listener<String>() {
          @Override
          public void onResponse(String response) {
              // Result handling
              System.out.println(response.substring(0,100));
          }
      }, new Response.ErrorListener() {
          @Override
          public void onErrorResponse(VolleyError error) {
               
              // Error handling
              System.out.println("Something went wrong!");
              error.printStackTrace();
          }
      });
      // Add the request to the queue
      Volley.newRequestQueue(this).add(stringRequest);

      正如你所看到的,這是非常簡單的。 您創(chuàng)建請求并將其添加到請求隊列。 你完成了。

      請注意,監(jiān)聽器的語法類似于AsyncTask.onPostExecute,只是它變成了onResponse。 這不是巧合。 使用Volley的開發(fā)人員有意使庫的API與AsyncTask 方法類似 。 這使得從使用AsyncTask切換到Volley更容易。

      如果您必須在多個activity中進行多個請求,則應(yīng)避免使用上述方法Volley.newRequestQueue.add。 最好是實例化一個共享的請求隊列,并在您的項目中使用它:

      1
      MySingletonClass.getInstance().getRequestQueue().add(myRequest);

      我們將在本系列的下一個教程中專門開發(fā)這樣的東西。

      4.  勝利在望

      處理標準要求

      Volley可以實現(xiàn)三種非常常見的請求類型:

      • StringRequest
      • ImageRequest
      • JsonRequest

      這些類中的每一個都繼承了我們之前使用的Result類。 我們已經(jīng)在前面的例子看過StringRequest了。 讓我們來看看JsonRequest工作原理。

      01
      02
      03
      04
      05
      06
      07
      08
      09
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      JsonObjectRequest jsonRequest = new JsonObjectRequest
              (Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
                  @Override
                  public void onResponse(JSONObject response) {
                      // the response is already constructed as a JSONObject!
                      try {
                          response = response.getJSONObject("args");
                          String site = response.getString("site"),
                                  network = response.getString("network");
                          System.out.println("Site: "+site+"\nNetwork: "+network);
                      } catch (JSONException e) {
                          e.printStackTrace();
                      }
                  }
              }, new Response.ErrorListener() {
                  @Override
                  public void onErrorResponse(VolleyError error) {
                      error.printStackTrace();
                  }
              });
      Volley.newRequestQueue(this).add(jsonRequest);

      美麗。 不是嗎? 您可以看到,結(jié)果類型已設(shè)置為JSONObject。 你也可以請求一個JSONArray如果你想要,使用JsonArrayRequest而不是一個JsonObjectRequest進請求。

      如前所述,構(gòu)造函數(shù)的第一個參數(shù)是要使用的HTTP方法。 然后,您可以提供從中獲取JSON的URL。 上面的例子中的第三個變量是  null。 這很好,因為它表示沒有參數(shù)將隨請求一起發(fā)出。 最后,您有監(jiān)聽器接收JSON響應(yīng)和錯誤響應(yīng)。 如果你想忽略錯誤,你可以傳入null  。

      獲取圖像需要做更多的工作。 有三種請求圖像的方法。  ImageRequest 是標準的。 它顯示在共同的ImageView中請求的圖片,該圖片通過提供的URL進行獲取。 您可能希望Volley執(zhí)行的所有解碼和調(diào)整大小操作都發(fā)生在工作線程上。 第二個選項是  ImageLoader 類,您可以將其視為大量的編排者ImageRequests,例如加載ListView 圖像。 第三個選項是  NetworkImageView,這是ImageView 布局項的一種XML替代。

      我們來看一個例子。

      01
      02
      03
      04
      05
      06
      07
      08
      09
      10
      11
      12
      13
      14
      15
      16
      17
      18
      String url = "http://i./Nwk25LA.jpg";
      mImageView = (ImageView) findViewById(R.id.image);
      ImageRequest imgRequest = new ImageRequest(url,
              new Response.Listener<Bitmap>() {
          @Override
          public void onResponse(Bitmap response) {
              mImageView.setImageBitmap(response);
          }
      }, 0, 0, ImageView.ScaleType.FIT_XY, Bitmap.Config.ARGB_8888, new Response.ErrorListener() {
          @Override
          public void onErrorResponse(VolleyError error) {
              mImageView.setBackgroundColor(Color.parseColor("#ff0000"));
              error.printStackTrace();
          }
      });
      Volley.newRequestQueue(this).add(imgRequest);

      第一個參數(shù)是圖片的URL,第二個參數(shù)是監(jiān)聽結(jié)果的監(jiān)聽器。 第三和第四個參數(shù)是整數(shù)maxWidth和  maxHeight。 您可以將它們設(shè)置0來忽略這些參數(shù)。 之后,ImageRequest 請求ScaleType用于計算所需的圖像大小和格式來解碼位圖。 我建議解碼格式總是使用Bitmap.Config.ARGB_8888。 最后,我們傳遞監(jiān)聽錯誤的監(jiān)聽器。

      請注意,Volley會自動將此請求的優(yōu)先級設(shè)置為LOW。

      1
      2
      3
      4
      5
      6
      // Snippet taken from ImageRequest.java,
      // in the Volley source code
      @Override
      public Priority getPriority() {
          return Priority.LOW;
      }

      發(fā)送POST請求

      從GET請求切換到POST請求很簡單。 您需要更改Request.Method 請求的構(gòu)造函數(shù)并重寫getParams方法,返回包含請求參數(shù)的Map<String, String> 。

      01
      02
      03
      04
      05
      06
      07
      08
      09
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      String url = "http:///post";
      StringRequest postRequest = new StringRequest(Request.Method.POST, url,
              new Response.Listener<String>() {
                  @Override
                  public void onResponse(String response) {
                      try {
                          JSONObject jsonResponse = new JSONObject(response).getJSONObject("form");
                          String site = jsonResponse.getString("site"),
                                  network = jsonResponse.getString("network");
                          System.out.println("Site: "+site+"\nNetwork: "+network);
                      } catch (JSONException e) {
                          e.printStackTrace();
                      }
                  }
              },
              new Response.ErrorListener() {
                  @Override
                  public void onErrorResponse(VolleyError error) {
                      error.printStackTrace();
                  }
              }
      ) {
          @Override
          protected Map<String, String> getParams()
          {
              Map<String, String>  params = new HashMap<>();
              // the POST parameters:
              params.put("site", "code");
              params.put("network", "tutsplus");
              return params;
          }
      };
      Volley.newRequestQueue(this).add(postRequest);

      取消請求

      如果要取消所有請求,請將以下代碼段添加到  onStop 方法中:

      01
      02
      03
      04
      05
      06
      07
      08
      09
      10
      11
      @Override
      protected void onStop() {
          super.onStop();
          mRequestQueue.cancelAll(new RequestQueue.RequestFilter() {
              @Override
              public boolean apply(Request<?> request) {
                  // do I have to cancel this?
                  return true; // -> always yes
              }
          });
      }

      這樣,您就不用擔心用戶在onResponse被調(diào)用時activity已經(jīng)被銷毀了的可能性。 因為在這種情況下會拋出NullPointerException異常。 

      然而,POST和PUT請求應(yīng)該繼續(xù),即使在用戶更改activity之后。 我們可以通過使用標簽來實現(xiàn)。 構(gòu)建GET請求時,向其添加一個標簽。

      1
      2
      3
      // after declaring your request
      request.setTag("GET");
      mRequestQueue.add(request);

      要取消所有待處理的GET請求,我們只需添加以下代碼行:

      1
      mRequestQueue.cancelAll("GET");

      這樣,您只能取消GET請求,使其他請求保持不變。 請注意,您現(xiàn)在必須手動處理activity過早銷毀的情況。

      管理Cookie和請求優(yōu)先級

      Volley不提供設(shè)置請求的Cookie的方法,也不提供設(shè)置優(yōu)先級。 這可能在將來研究,因為它是一個嚴重的遺漏。 但是,暫時還要繼承Request類。

      對于管理cookies,您可以使用請求的標題來重寫getHeaders 方法:

      01
      02
      03
      04
      05
      06
      07
      08
      09
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      public class CustomRequest extends JsonObjectRequest {
          // Since we're extending a Request class
          // we just use its constructor
          public CustomRequest(int method, String url, JSONObject jsonRequest,
                               Response.Listener<JSONObject> listener, Response.ErrorListener errorListener) {
              super(method, url, jsonRequest, listener, errorListener);
          }
          private Map<String, String> headers = new HashMap<>();
          /**
           * Custom class!
           */
          public void setCookies(List<String> cookies) {
              StringBuilder sb = new StringBuilder();
              for (String cookie : cookies) {
                  sb.append(cookie).append("; ");
              }
              headers.put("Cookie", sb.toString());
          }
          @Override
          public Map<String, String> getHeaders() throws AuthFailureError {
              return headers;
          }
           
      }

      實現(xiàn)后,您可以使用setCookies直接提供請求的Cookie列表。

      01
      02
      03
      04
      05
      06
      07
      08
      09
      10
      11
      12
      // Firstly, you create the list of the cookies,
      // conformed to the HTTP conventions
      // i.e. key=value
      List<String> cookies = new ArrayList<>();
      cookies.add("site=code");
      cookies.add("network=tutsplus");
      // then you invoke your custom method
      customRequest.setCookies(cookies);
      // and finally add the request to the queue
      Volley.newRequestQueue(this).add(customRequest);

      對于優(yōu)先級,您還需要繼承Request類,重寫getPriority 方法。 實現(xiàn)如下:

      01
      02
      03
      04
      05
      06
      07
      08
      09
      10
      11
      12
      Priority mPriority;
      public void setPriority(Priority priority) {
          mPriority = priority;
      }
      @Override
      public Priority getPriority() {
          // If you didn't use the setPriority method,
          // the priority is automatically set to NORMAL
          return mPriority != null ? mPriority : Priority.NORMAL;
      }

      然后,在主線程上,調(diào)用這一行代碼來設(shè)置請求的優(yōu)先級:

      1
      customRequest.setPriority(Priority.HIGH);

      您可以選擇以下四個可能的優(yōu)先級狀態(tài)之一:

      1
      2
      3
      4
      Priority.LOW // images, thumbnails, ...
      Priority.NORMAL // residual
      Priority.HIGH // descriptions, lists, ...
      Priority.IMMEDIATE // login, logout, ...

      結(jié)論

      在本文中,我們研究了Volley網(wǎng)絡(luò)庫的工作原理。 我們首先看到了為什么使用Volley,何時使用Volley而不是已經(jīng)包含在Android SDK中的另一個解決方案。 然后,我們深入了解該庫的細節(jié),查看其工作流程及其支持的請求類型。 最后,我們通過創(chuàng)建簡單的請求并實現(xiàn)自定義的請求來處理cookie和優(yōu)先級,從而達到我們的目的。

      在本系列關(guān)于Volley的下一部分中,我們將創(chuàng)建一個利用Volley的簡單應(yīng)用程序。 我將展示如何制作火星天氣應(yīng)用程序,使用好奇流動站在火星上收集的天氣數(shù)據(jù)。

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多