2016-07-25 39 views
4

壞事使用抽射處理大反應時發生的事情:的Android,排球請求,響應阻塞主線程

String url = AppHelper.DOMAIN + "/service/pages/profile_update.json"; 

this.infoTextView.setText(getString(R.string.profile_info_updating)); 

final StringRequest stringRequest = new StringRequest(Request.Method.POST, url, 
     new Response.Listener<String>() { 
      @Override 
      public void onResponse(String response) { 
       try { 
        JSONObject json = new JSONObject(response); 

        if (json.getBoolean("success")) { 
         // manage JSON object here 
        } else { 
         Toast.makeText(ProfileActivity.this, 
           getString(R.string.connection_problem_server), 
           Toast.LENGTH_LONG).show(); 
        } 
       } catch (JSONException e) { 
        ProfileActivity.this.infoTextView.setText(
          getString(R.string.profile_info_updating_error)); 

        e.printStackTrace(); 
       } 
      } 
     }, new Response.ErrorListener() { 
    @Override 
    public void onErrorResponse(VolleyError error) { 
     ProfileActivity.this.infoTextView.setText(
       getString(R.string.profile_info_updating_error)); 

     if (error.networkResponse != null && error.networkResponse.statusCode == 401) { 
      Toast.makeText(ProfileActivity.this, 
        getString(R.string.connection_problem_permission), 
        Toast.LENGTH_LONG).show(); 
     } 

     new android.os.Handler().postDelayed(new Runnable() { 
      @Override 
      public void run() { 
       if (ProfileActivity.this.swipeRefreshLayout != null) { 
        ProfileActivity.this.swipeRefreshLayout.setRefreshing(false); 
       } 
      } 
     }, 1000); 

     error.printStackTrace(); 
    } 
}) { 
    @Override 
    protected Map<String, String> getParams() { 
     Map<String, String> params = new HashMap<>(); 
     params.put("auth_token", ProfileActivity.this.defaultUser.getAuthenticationToken()); 
     return params; 
    } 

    @Override 
    public Map<String, String> getHeaders() throws AuthFailureError { 
     Map<String, String> params = new HashMap<>(); 
     params.putAll(super.getHeaders()); 
     params.put("Accept-Encoding", "gzip,deflate"); 
     return params; 
    } 

    @Override 
    protected Response<String> parseNetworkResponse(NetworkResponse response) { 
     StringBuilder output = new StringBuilder(); 
     try { 
      GZIPInputStream gStream = new GZIPInputStream(new ByteArrayInputStream(response.data)); 
      InputStreamReader reader = new InputStreamReader(gStream); 
      BufferedReader in = new BufferedReader(reader, 16384); 

      String read; 

      while ((read = in.readLine()) != null) { 
       output.append(read).append("\n"); 
      } 
      reader.close(); 
      in.close(); 
      gStream.close(); 
     } catch (IOException error) { 
      error.printStackTrace(); 
      return Response.error(new ParseError()); 
     } 

     return Response.success(output.toString(), HttpHeaderParser.parseCacheHeaders(response)); 
    } 
}; 

stringRequest.setRetryPolicy(new RetryPolicy() { 
    @Override 
    public int getCurrentTimeout() { 
     // 40 seconds 
     return 40000; 
    } 

    @Override 
    public int getCurrentRetryCount() { 
     return DefaultRetryPolicy.DEFAULT_MAX_RETRIES; 
    } 

    @Override 
    public void retry(VolleyError error) throws VolleyError { 
     throw error; 
    } 
}); 

Volley.newRequestQueue(this).add(stringRequest); 

這個代碼塊爲主線,凍結的申請。

此外,我設置了一些標頭值以允許gzip響應和代碼來處理數據。但這並不是造成不良行爲的因素。僅當onResponse(String response)開始時,應用程序纔會凍結。

我該怎麼做才能避免這種情況?

+1

,可能還存在的事實,你正在做的,而不是在JSON解析UI線程上,做'parseNetworkResponse' – EpicPandaForce

+0

代碼似乎是罰款..你可以暴露此網絡請求周圍的代碼的其他部分? – Dexto

回答

9

onResponse和onErrorResponse在UI線程上調用,因此在這些方法中執行的任何繁重操作都會使應用程序的響應速度變慢。我想你正試圖解析onResponse()中的響應,這是不正確的。

因爲這個 是在後臺線程中調用的方法,所以你必須移動到解析邏輯來解析網絡響應。請參考以下鏈接瞭解詳情:

https://developer.android.com/training/volley/request-custom.html

+1

謝謝你的回答! – zerokol

+0

如果調用請求是由IntentService創建的,那麼onResponse()會在UI線程上執行呢? –

+0

Doest不管什麼是調用線程。 onResponse()將在UI線程上調用。 –