2015-04-02 65 views
-1

我有一個異步任務從服務器加載信息並在UI上顯示數據。突然異步任務下載數據並格式化JSON數據,但它會完全凍結UI。Android異步任務完全凍結UI

這裏是基下載類

public class GetRawData { 

private static String LOG_TAG = GetRawData.class.getSimpleName(); 
private String mRawURL; 
private List<NameValuePair> mRawParams = null; 
private String mRawData; 
private DownloadStatus mDownloadStatus; 

public GetRawData(String mRawURL) { 
    this.mRawURL = mRawURL; 
    this.mRawParams = null; 
    this.mDownloadStatus = DownloadStatus.IDLE; 
} 

public String getRawData() { 
    return mRawData; 
} 

public void setRawURL(String mRawURL) { 
    this.mRawURL = mRawURL; 
} 

public List<NameValuePair> getRawParams() { 
    return mRawParams; 
} 

public void setRawParams(List<NameValuePair> mParams) { 
    this.mRawParams = mParams; 
} 

public DownloadStatus getDownloadStatus() { 
    return mDownloadStatus; 
} 

public void reset() { 
    this.mRawURL = null; 
    this.mRawData = null; 
    this.mDownloadStatus = DownloadStatus.IDLE; 
} 

public void execute() { 
    this.mDownloadStatus = DownloadStatus.PROCESSING; 
    DownloadRawData mDownloadRawData = new DownloadRawData(); 
    mDownloadRawData.execute(mRawURL); 
} 

public class DownloadRawData extends AsyncTask<String, Void, String> { 
    @Override 
    protected String doInBackground(String... params) { 
     // Create URL and Reader instances. 
     HttpURLConnection urlConnection = null; 
     BufferedReader reader = null; 

     //If no parameter has been provided, return null. 
     if (params == null) 
      return null; 

     try { 
      // Get URL entered by the user. 
      URL mURL = new URL(params[0]); 

      urlConnection = (HttpURLConnection) mURL.openConnection(); 
      urlConnection.setDoOutput(true); 
      urlConnection.setRequestMethod("POST"); 
      urlConnection.setUseCaches(false); 
      urlConnection.setConnectTimeout(10000); 
      urlConnection.setReadTimeout(10000); 
      urlConnection.setRequestProperty("Content-Type","application/json"); 

      //urlConnection.setRequestProperty("Host", "android.schoolportal.gr"); 
      urlConnection.connect(); 

      // validate and add parameters if available. 
      if (mRawParams != null && mRawParams.size()>0){ 
       JSONObject jsonParam = new JSONObject(); 

       for (NameValuePair pair : mRawParams) { 
        jsonParam.put(pair.getName().toString(), pair.getValue().toString()); 
       } 

       String jsonparams = jsonParam.toString(); 

       // Send POST output. 
       DataOutputStream printout; 
       printout = new DataOutputStream(urlConnection.getOutputStream()); 
       printout.writeBytes(jsonparams); 
       printout.flush(); 
       printout.close(); 
      } 

      int HttpResult =urlConnection.getResponseCode(); 

      StringBuffer buffer = new StringBuffer(); 
      if(HttpResult ==HttpURLConnection.HTTP_OK){ 
       InputStream inputStream = urlConnection.getInputStream(); 
       if (inputStream == null) { 
        return null; 
       } 
       reader = new BufferedReader(new InputStreamReader(inputStream)); 

       String line; 
       while ((line = reader.readLine()) != null) { 
        buffer.append(line + "\n"); 
       } 
       System.out.println(""+buffer.toString()); 

      }else{ 

       InputStream errorStream = urlConnection.getErrorStream(); 
       if (errorStream == null) { 
        return null; 
       } 
       reader = new BufferedReader(new InputStreamReader(errorStream)); 

       String line; 
       while ((line = reader.readLine()) != null) { 
        buffer.append(line + "\n"); 
       } 
       System.out.println(urlConnection.getResponseMessage()); 
      } 


      return buffer.toString(); 

     } catch (IOException e) { 
      Log.d("IOException", e.toString()); 
      return null; 
     } catch (JSONException j) { 
      Log.d("JSONException", j.toString()); 
      return null; 
     } finally { 
      if (urlConnection != null) { 
       urlConnection.disconnect(); 
      } 
      if (reader != null) { 
       try { 
        reader.close(); 
       } catch (IOException e) { 
        Log.d("IOException", "unable to close the reader"); 
       } 
      } 
     } 
    } 

    @Override 
    protected void onPostExecute(String result) { 
     super.onPostExecute(result); 
     mRawData = result; 
     //Log.d("onPostExecute", result); 

     if (mRawData == null) { 
      if (mRawURL == null) { 
       mDownloadStatus = DownloadStatus.NOT_INITIALIZED; 
      } else { 
       mDownloadStatus = DownloadStatus.FAILED_OR_EMPTY; 
      } 
     } else { 
      mDownloadStatus = DownloadStatus.PROCESSED; 
     } 
    } 

    private String getQuery(List<NameValuePair> params) throws UnsupportedEncodingException { 
     StringBuilder result = new StringBuilder(); 
     boolean first = true; 

     for (NameValuePair pair : params) { 
      if (first) 
       first = false; 
      else 
       result.append("&"); 

      result.append(URLEncoder.encode(pair.getName(), "UTF-8")); 
      result.append("="); 
      result.append(URLEncoder.encode(pair.getValue(), "UTF-8")); 
     } 

     return result.toString(); 
    } 
} 

} 
enum DownloadStatus { 
IDLE, 
PROCESSING, 
NOT_INITIALIZED, 
FAILED_OR_EMPTY, 
PROCESSED 
} 

下面是特定數據格式類上面的類

public class GetJobCardJsonData extends GetRawData { 
private static String LOG_TAG = GetAuthenticationJsonData.class.getSimpleName(); 
private static String JOBCARD_SERVICE_URL = "http://www.appservice.com/appservice/jobcardinfoservice.asmx/GetJobCardInfo"; 
private List<JobCard> mJobCardList; 
private CarcalDownloadListener mListener; 

public GetJobCardJsonData(String CurrentDate, int DealershipID) { 
    super(null); 

    List<NameValuePair> mParams = new ArrayList<NameValuePair>(); 
    mParams.add(new BasicNameValuePair("JobCardDate", CurrentDate)); 
    mParams.add(new BasicNameValuePair("DealershipID", String.valueOf(DealershipID))); 
    this.setRawParams(mParams); 
} 

public List<JobCard> getJobCardList() { 
    return mJobCardList; 
} 

public void getjobcards() { 
    super.setRawURL(JOBCARD_SERVICE_URL); 
    DownloadJobCardJsonData mDownloadJobCardJsonData = new DownloadJobCardJsonData(); 
    mDownloadJobCardJsonData.execute(JOBCARD_SERVICE_URL); 
} 

public void setOnCarcalDownloadListener(CarcalDownloadListener onCarcalDownloadListener) { 
    this.mListener = onCarcalDownloadListener; 
} 

private void processResult() { 
    if (getDownloadStatus() != DownloadStatus.PROCESSED) { 
     Log.e(LOG_TAG, "Error Downloading the raw file."); 
     return; 
    } 

    if (mJobCardList == null){ 
     mJobCardList = new ArrayList<JobCard>(); 
    } 

    final String JOBCARD_JOBCARDID = "JobCardID"; 
    final String JOBCARD_GETSTOCKNUMBER_WITH_DELIVERYTIME = "StockNumberWithDeliveryTime"; 
    final String JOBCARD_CUSTOMERNAME = "CustomerName"; 
    final String JOBCARD_MODELNUMBER = "ModelNumber"; 
    final String JOBCARD_COLOR = "Color"; 
    final String JOBCARD_SALEEXECUTIVE = "SaleExecutive"; 
    final String JOBCARD_ORDERSTATUS = "OrderStatus"; 
    final String JOBCARD_SHOWROOMSTATUS = "ShowRoomStatus"; 

    try { 
     JSONArray jsonArray = new JSONArray(getRawData()); 

     for (int i = 0; i < jsonArray.length(); i++) { 
      JSONObject jobcarditem = jsonArray.optJSONObject(i); 

      Long JOBCARDID = jobcarditem.getLong(JOBCARD_JOBCARDID); 
      String STOCKWITHDELIVERY = jobcarditem.getString(JOBCARD_GETSTOCKNUMBER_WITH_DELIVERYTIME); 
      String CUSTOMERNAME = jobcarditem.getString(JOBCARD_CUSTOMERNAME); 
      String MODELNUMBER = jobcarditem.getString(JOBCARD_MODELNUMBER); 
      String COLOR = jobcarditem.getString(JOBCARD_COLOR); 
      String SALEEXECUTIVE = jobcarditem.getString(JOBCARD_SALEEXECUTIVE); 
      int ORDERSTATUS = jobcarditem.getInt(JOBCARD_ORDERSTATUS); 
      int SHOWROOMSTATUS = jobcarditem.getInt(JOBCARD_SHOWROOMSTATUS); 

      JobCard mJobCard = new JobCard(JOBCARDID, STOCKWITHDELIVERY, CUSTOMERNAME, MODELNUMBER, COLOR, SALEEXECUTIVE, ORDERSTATUS, SHOWROOMSTATUS); 
      mJobCardList.add(mJobCard); 
     } 

    } catch (JSONException jsone) { 
     jsone.printStackTrace(); 
     Log.e(LOG_TAG, "Error processing json data."); 
    } 

} 

public class DownloadJobCardJsonData extends DownloadRawData { 
    @Override 
    protected String doInBackground(String... params) { 
     return super.doInBackground(params[0]); 
    } 

    @Override 
    protected void onPostExecute(String result) { 
     super.onPostExecute(result); 
     processResult(); 
     mListener.OnDownloadCompleted(); 
    } 
} 

} 

在這裏,延伸的是,被稱爲上的活動的代碼

private JobCardRecyclerViewAdapter mJobCardRecyclerViewAdapter; 
private GetJobCardJsonData mGetJobCardJsonData; 
SessionManager session; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_job_card_calender); 
    activateToolbarWithHomeEnabled(); 

    String formattedDate=""; 
    if (session.getCurrentDate() == ""){ 
     Calendar c = Calendar.getInstance(); 
     SimpleDateFormat df = new SimpleDateFormat("MM/dd/yyyy"); 
     formattedDate = df.format(c.getTime()); 
     currentDateTextView.setText(formattedDate); 
    }else { 
     formattedDate = session.getCurrentDate(); 
     currentDateTextView.setText(formattedDate); 
    } 

    // Fetch data for current date. 
     mGetJobCardJsonData = new GetJobCardJsonData(formattedDate, session.getDealershipID()); 
     mGetJobCardJsonData.getjobcards(); 
     mGetJobCardJsonData.setOnCarcalDownloadListener(new CarcalDownloadListener() { 
      @Override 
      public void OnDownloadCompleted() { 
       List<JobCard> mJobCards = mGetJobCardJsonData.getJobCardList(); 
       mJobCardRecyclerViewAdapter = new JobCardRecyclerViewAdapter(mJobCards, JobCardCalenderActivity.this); 
       mRecyclerView.setAdapter(mJobCardRecyclerViewAdapter); 
      } 
     }); 

} 

任何人都可以幫助我正在做的錯誤是凍結用戶界面。它之前工作正常,並且突然開始凍結UI。

+1

使用Traceview,也許'StrictMode'來確定你在主應用程序線程上的時間。 – CommonsWare 2015-04-02 11:53:52

+0

感謝您的及時響應,我對android開發很天真。你能提供一個我們如何使用StrictMode來跟蹤UI線程的例子嗎? – 2015-04-02 12:01:41

回答

0

我能夠解決這個問題,問題不是與異步任務,但與佈局。我意外地用滾動視圖包裝了回收站視圖。這導致UI凍結。看起來很奇怪,滾動視圖導致整個UI線程凍結。但這裏是我的解決方案

<ScrollView 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

    <view 
     android:id="@+id/jobCardRecyclerView" 
     class="android.support.v7.widget.RecyclerView" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_below="@id/jobCardHeader" 
     android:scrollbars="vertical"></view> 

</ScrollView> 

改成了

<view 
     android:id="@+id/jobCardRecyclerView" 
     class="android.support.v7.widget.RecyclerView" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_below="@id/jobCardHeader" 
     android:scrollbars="vertical"></view> 

希望這將是對其他面臨同樣的問題很有幫助。