標籤:android asynctask 異常 網路 線程
大家肯定都會經常使用AsyncTask這個類,特別是在網路處理中,先看改正後的代碼:這是正常的代碼:
class sendKeyTask extends AsyncTask<String, Void, Integer>{@Overrideprotected void onPostExecute(Integer resultCode) {// TODO Auto-generated method stubsuper.onPostExecute(resultCode);switch (resultCode) {case 6000:NotifyHelper.popNotifyInfo(InnerQuestionActivity.this, "使用者資訊異常", "");break;case 6001:NotifyHelper.popNotifyInfo(InnerQuestionActivity.this, "其他異常", "");break;case 6002:break;default:break;}// 隱藏IMEInputMethodManager imm = (InputMethodManager) getApplicationContext().getSystemService(Context.INPUT_METHOD_SERVICE);// 顯示或者隱藏IMEimm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);innerQuestionEdit.setText("");//從新重新整理new getQuestionDetailTack().execute(1);}@Overrideprotected Integer doInBackground(String... data) {// TODO Auto-generated method stubint resultCode=4001;HttpClient client= new DefaultHttpClient();HttpPost post = new HttpPost("http://diandianapp.sinaapp.com/add_key.php");StringBuilder builder = new StringBuilder(); List<NameValuePair> paramsList=new ArrayList<NameValuePair>();paramsList.add(new BasicNameValuePair("access_token", data[0]));paramsList.add(new BasicNameValuePair("user_name", data[1]));paramsList.add(new BasicNameValuePair("key_detail", data[2]));paramsList.add(new BasicNameValuePair("question_id", data[3]));for(int i=0;i<jpegDataList.size();i++){paramsList.add(new BasicNameValuePair("img"+String.valueOf(i), jpegDataList.get(i)));}try {post.setEntity( new UrlEncodedFormEntity(paramsList,HTTP.UTF_8));} catch (UnsupportedEncodingException e1) {e1.printStackTrace();}try { HttpResponse response = client.execute(post); HttpEntity entity = response.getEntity();BufferedReader reader = new BufferedReader(new InputStreamReader(entity.getContent())); for (String s = reader.readLine(); s != null; s = reader.readLine()) { builder.append(s); } JSONObject jsonObject = new JSONObject(builder.toString());String stateCodeStr = jsonObject.getString("state_code"); resultCode=Integer.parseInt(stateCodeStr);} catch (ClientProtocolException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (JSONException e) {// TODO Auto-generated catch blocke.printStackTrace();//處理請求失敗}finally{}return resultCode;}}
可能有人會說,我讓doInBackground返回一個參數,再在onPostExecute裡面處理不是多次一舉嗎?但是,當你真的將兩部分合成後,會發現,竟然報錯了!報錯內容大體為UI內容只能在主線程更改;這是為什麼呢!
NotifyHelper.popNotifyInfo(InnerQuestionActivity.this, "其他異常", "");是對對話提示框的一個彈出方法封裝,這是對UI介面的操作,問題應該就出在這兒了!
我們翻開google的說明看下:
protected abstract Result doInBackground (Params... params)Added in API level 3
Override this method to perform a computation on a background thread. The specified parameters are the parameters passed toexecute(Params...) by the caller of this task. This method can callpublishProgress(Progress...) to publish updates on the UI thread.
Parameters
| params |
The parameters of the task. |
Returns
- A result, defined by the subclass of this task.
protected void onPostExecute(Result result) Added in API level 3
Runs on the UI thread after doInBackground(Params...). The specified result is the value returned bydoInBackground(Params...).
This method won‘t be invoked if the task was cancelled.
Parameters
| result |
The result of the operation computed by doInBackground(Params...). |
See Alsoprotected void onPreExecute() Added in API level 3
Runs on the UI thread before doInBackground(Params...).
我們可以看出,這幾個重載方法只有doInBackground是在後台線程啟動並執行,而後台是不能執行更新線程的操作的!
我們必須要在doInbackground中,返回耗時操作的處理結果,再從onPostExecute中根據doInBackground返回的參數進行UI組件的操作!
doInBackground
Android AsyncTask使用心得及錯誤處理-只能在主線程改變UI組件