我尝试修改AsyncTaks中的Spinner内容,但我不能和Logcat写的“09-19 16:36:11.189:ERROR / ERROR THE(6078):只创建视图层次结构的原始线程可以触及它的观点。“。
public class GetGroups extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... params) {
Spinner combo = (Spinner) findViewById(R.id.group_combo);
setGroups(combo);
return null;
}
@Override
protected void onPostExecute(Void unused)
{
super.onPostExecute(unused);
Spinner combo = (Spinner) findViewById(R.id.severity_combo);
combo.setSelection(1);
//updateGroups();
//if (!isFinishing())
//{
/*Spinner combo = (Spinner) findViewById(R.id.group_combo);
ProgressBar pg = (ProgressBar) findViewById(R.id.loading_group);
pg.setVisibility(ProgressBar.GONE);
combo.setVisibility(Spinner.VISIBLE);
combo.setSelection(0);*/
//}
}
}
}
函数setGroups是:
public void setGroups(Spinner combo) {
try {
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(this.object.url);
List<NameValuePair> parameters = new ArrayList<NameValuePair>(2);
parameters.add(new BasicNameValuePair("user", this.object.user));
parameters.add(new BasicNameValuePair("pass", this.object.password));
parameters.add(new BasicNameValuePair("op", "get"));
parameters.add(new BasicNameValuePair("op2", "groups"));
parameters.add(new BasicNameValuePair("other_mode", "url_encode_separator_|"));
parameters.add(new BasicNameValuePair("return_type", "csv"));
parameters.add(new BasicNameValuePair("other", ";"));
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(parameters);
httpPost.setEntity(entity);
HttpResponse response = httpClient.execute(httpPost);
HttpEntity entityResponse = response.getEntity();
String return_api = this.object.convertStreamToString(entityResponse.getContent());
String[] lines = return_api.split("\n");
ArrayList<String> array = new ArrayList<String>();
for (int i= 0; i < lines.length; i++) {
String[] groups = lines[i].split(";", 21);
this.pandoraGroups.put(new Integer(groups[0]), groups[1]);
array.add(groups[1]);
}
ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_item,
array);
combo.setAdapter(spinnerArrayAdapter);
}
catch (Exception e) {
Log.e("ERROR THE ", e.getMessage());
return;
}
}
有什么问题?感谢。
答案 0 :(得分:26)
如Peter所述,您无法使用doInBackground()
访问视图。但是,您可以在onPostExecute()
内执行此操作。据我所知,这就是你应该使用结果doInBackground()
返回的地方。
我遇到了这个问题并通过将视图修改代码移动到onPostExecute()
来修复它。
对于那些开始接受Android开发的人:
- doInBackground()
:在另一个线程(在后台)发生的内容与您的views / fragment / activity操作的主/原始线程不同(这是AsyncTask
==&gt;你的全部内容无法触及意见!
- onPostExecute()
:现在已经完成了背景资料,这里又回到主/线程主题==&gt;您现在可以触摸视图!
答案 1 :(得分:10)
您正尝试在doInBackground()
方法中的案例中从后台线程访问UI组件(View)。你是not allowed to do that。
答案 2 :(得分:3)
如果您想在后台进程中显示进度,以前的答案都没有给出提示:当OnPostExecute
被调用时,一切都已完成,因此无需更新加载状态。
因此,您必须在AsyncTask中覆盖onProgressUpdate
,并确保第二个对象不是Void,而是由onProgressUpdate
读取的整数或字符串。例如,使用String:
public class MyAsyncTask extends AsyncTask<Void, String, Void> {
@Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
if (values != null && values.length > 0) {
//Your View attribute object in the activity
// already initialized in the onCreate!
mStatusMessageView.setText(values[0]);
}
}
}
比在后台方法中调用publishProgress(value as String)
,它会自动调用使用主UI线程的onProgressUpdate
方法:
@Override
protected Boolean doInBackground(Void... params) {
your code...
publishProgress("My % status...");
your code...
publishProgress("Done!");
}
更一般地说,当你声明一个AsyncTask时,你必须指定传递给main方法的<Params, Progress, Result>
类,这些类可以是你自己的类,也可以只是Java类:
doInBackground(Params... params)
onProgressUpdate(Progress... value)
onPostExecute(Result... success)
答案 3 :(得分:3)
更多细节
<强>问题强>:
postInvalidate()
方法(及其变体)可以在UI Thread View
)引起的 - doInBackground()
在后台线程上运行<强>解决方案强>:
onPostExecute()
方法中的视图 - 它在UI线程上运行Activity
的引用并使用其runOnUiThread(Runnable)
方法View
的{{1}}方法之一