Android异步任务完全冻结UI

时间:2015-04-02 11:50:33

标签: android user-interface asynchronous android-asynctask

我有一个异步任务,可以从服务器加载信息并在UI上显示数据。突然,异步任务下载数据并格式化JSON数据,但它会完全冻结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 个答案:

答案 0 :(得分:0)

我能够解决问题,问题不在于Async任务,而在于布局。我意外地用回滚视图包裹了回收者视图。这导致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>

希望它对面临同样问题的其他人有所帮助。