从另一个类文件中调用setListAdapter

时间:2013-02-19 15:45:03

标签: android android-asynctask listadapter

我有一个这样的类文件:

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吗?如何实现这一目标?

3 个答案:

答案 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构造函数。