您的位置:首页 > 产品设计 > UI/UE

Android AsyncTask使用心得及错误处理-只能在主线程改变UI组件

2015-05-05 13:31 344 查看
大家肯定都会经常使用AsyncTask这个类,特别是在网络处理中,先看改正后的代码:这是正常的代码:

class sendKeyTask extends AsyncTask<String, Void, Integer>
{

@Override
protected void onPostExecute(Integer resultCode) {
// TODO Auto-generated method stub
super.onPostExecute(resultCode);
switch (resultCode) {
case 6000:
NotifyHelper.popNotifyInfo(InnerQuestionActivity.this, "用户信息异常", "");
break;
case 6001:
NotifyHelper.popNotifyInfo(InnerQuestionActivity.this, "其他异常", "");
break;
case 6002:

break;
default:
break;
}
// 隐藏输入法
InputMethodManager imm = (InputMethodManager) getApplicationContext().getSystemService(Context.INPUT_METHOD_SERVICE);
// 显示或者隐藏输入法
imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
innerQuestionEdit.setText("");
//从新刷新
new getQuestionDetailTack().execute(1);

}

@Override
protected Integer doInBackground(String... data) {
// TODO Auto-generated method stub
int 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 block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.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 to
execute(Params...)
by the caller of this task. This method can call
publishProgress(Progress...)
to publish updates on the UI thread.

Parameters
paramsThe 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 by
doInBackground(Params...)
.

This method won't be invoked if the task was cancelled.

Parameters
resultThe result of the operation computed by
doInBackground(Params...)
.
See Also

protected void onPreExecute
()

Added in API level 3

Runs on the UI thread before
doInBackground(Params...)
.

我们可以看出,这几个重载方法只有doInBackground是在后台线程运行的,而后台是不能执行更新线程的操作的!

我们必须要在doInbackground中,返回耗时操作的处理结果,再从onPostExecute中根据doInBackground返回的参数进行UI组件的操作!

doInBackground
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: