我有一个这样的类文件:
public class Search_Results extends SherlockListActivity{
String result = "";
SearchView searchView;
Context context = this;
private Intent intent = null;
private String searchThis = "";
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setTheme(R.style.Sherlock___Theme_DarkActionBar);
setContentView(R.layout.search_results);
ListView myList=(ListView)findViewById(android.R.id.list);
ProgressBar progress = (ProgressBar)findViewById(R.id.progress_spin);
intent = getIntent();
searchThis = intent.getStringExtra(Home.SEARCH_SERVICE);
new Retrieve(context, progress, searchThis, myList).execute("");
}//onCreate
}
这会调用另一个java文件中的新Retrieve()
并扩展AsyncTask
public class Retrieve extends AsyncTask <String, Integer, ArrayList<String>>{
private Context context;
private String title = "";
private ArrayList<String> list = null;
private ArrayList<NameValuePair> nameValuePairs = null;
private String result = "";
private ProgressBar progress;
private String searchThis;
private ListView mylist;
//constructor
public Retrieve(Context context, ProgressBar progress, String searchThis, ListView myList) {
this.context = context;
this.progress = progress;
this.searchThis = searchThis;
this.mylist = myList;
}
protected ArrayList<String> doInBackground(String... params){
progress.setVisibility(View.VISIBLE);
InputStream is = null;
list = new ArrayList<String>();
nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("searchThis", searchThis));
try{
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(URL);
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
is = entity.getContent();
}
catch(Exception e){
Log.e("CONNECTION_ERROR", "Error in http connection "+e.toString());
}
try{
BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null){
sb.append(line + "\n");
}
is.close();
result=sb.toString();
}
catch(Exception e){
Log.e("BUFFER_ERROR", "Error converting result "+e.toString());
}
if(result.equalsIgnoreCase("null\n")){
list.add("empty");
}
else{
try{
JSONArray jArray = new JSONArray(result);
for(int i=0;i<jArray.length();i++){
JSONObject json_data = jArray.getJSONObject(i);
title = json_data.getString("title");
list.add(title);
}
}
catch(JSONException e){
Log.e("DATA_PARSING_ERROR", "Error parsing data "+e.toString());
}
}
return list;
}
@Override
protected void onPostExecute(ArrayList<String> list){
progress.setVisibility(View.GONE);
ArrayAdapter<String> mArrayAdapter = new ArrayAdapter<String>(context, R.layout.list_display, list);
//PROBLEM
mylist.setAdapter(mArrayAdapter);
}
}//Retrieve
我首先只尝试setListAdapter(mArrayAdapter)
但是显然java并不知道要更新的列表,然后我尝试将列表传递给构造函数
ListView myList=(ListView)findViewById(android.R.id.list);
我收到了这个错误:
android.view.ViewRootImpl$CalledFromWrongThreadException:
Only the original thread that created a view hierarchy can touch its views.
也许是因为我试图改变另一个班级的观点?我该如何解决这个问题? onPostExecute
函数应该返回mArrayAdapter
吗?如何实现这一目标?
答案 0 :(得分:1)
您正在获取Only the original thread that created a view hierarchy can touch its views.
,因为您正在尝试从doInBackground访问UI元素。所以只需将它从doInBackground移到外面,然后将它移到onPreExecute中:
@Override
protected void onPreExecute() {
super.onPreExecute();
progress.setVisibility(View.VISIBLE); //<< set here
}
答案 1 :(得分:1)
您可能想要创建适配器并将其设置在Search_Results活动中。列表的适配器应该是列表所在的Activity的一个组件。您希望避免将UI与这样的AsyncTask紧密耦合,即您的Retrieve
类只需要工作并返回,不知道关于它获得的数据会发生什么的详细信息。
我会在Search_Results中创建一个公共方法(例如,updateAdapter
),您可以使用onPostExecute
方法调用该方法。您可以从context
类的Retrieve
成员变量中调用它:
public void updateAdapter(ArrayList<String> list) {
ArrayAdapter<String> mArrayAdapter = new ArrayAdapter<String>(Search_Results.this, R.layout.list_display, list);
setListAdapter(mArrayAdapter);
}
在onPostExecute
:
@Override
protected void onPostExecute(ArrayList<String> list){
progress.setVisibility(View.GONE);
context.updateAdapter(list);
}
答案 2 :(得分:0)
您可以将ListActivity
对象而不是ListView
传递给Retrieve
构造函数。