0

我有一个这样的类文件:

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
}

这会调用Retrieve()另一个 java 文件上的 new 并扩展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? 如何实现?

4

3 回答 3

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
    }
于 2013-02-19T15:53:52.343 回答
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);
}
于 2013-02-19T16:07:00.537 回答
0

您可以将ListActivity对象传递ListView给您的Retrieve构造函数。

于 2013-02-19T16:07:25.297 回答