代码之家  ›  专栏  ›  技术社区  ›  jul

在AsyncTask类中设置ListView时出现问题

  •  1
  • jul  · 技术社区  · 15 年前

    谢谢

    public class Atable extends Activity {
    
        private EditText mSearch;
        private static final int ACTIVITY_EDIT=0;
        private Button mSearchButton;
        private TextView mNoresults;
        private ListView lv;
        private CheckBox checkBox;
        private LocationManager locationManager;
        private RestaurantList restaurantList;
        private Criteria criteria;
    
        public void onCreate(Bundle savedInstanceState) {
    
            super.onCreate(savedInstanceState);
    
            setContentView(R.layout.main);
    
            lv= (ListView)findViewById(R.id.listview);
    
            mNoresults = (TextView) findViewById(R.id.noresults);  
            mNoresults.setVisibility(View.GONE);
    
            mSearchButton = (Button)this.findViewById(R.id.button);
            checkBox = (CheckBox) findViewById(R.id.local_check);        
    
            locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
            criteria = new Criteria();
            criteria.setAccuracy(Criteria.ACCURACY_FINE);
    
            mSearchButton.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    mNoresults.setVisibility(View.GONE);
                    mSearch = (EditText) findViewById(R.id.search);  
                    String tmp_str = mSearch.getText().toString().replace(" ","+");  
                    String url = "http://www.atable.org/getRestaurantByQuery/?query=" + tmp_str;
    
                    if (checkBox.isChecked()) {
    
                        //get location
                        String provider = locationManager.getBestProvider(criteria, true);                
                        Location location = locationManager.getLastKnownLocation(provider);
    
                        if (location!=null) {
    
                            String lat = String.valueOf(location.getLatitude());
                            String lng = String.valueOf(location.getLongitude());
    
                            url += "&lat="+lat+"&lng="+lng;                   
                        }
                    }
                    new GetRestaurantData().execute(url);               
                }
            });
    
        };
    
        private class GetRestaurantData extends AsyncTask<String, Boolean, RestaurantList> {
    
            private HttpClient httpclient = new DefaultHttpClient();
    
            @Override
            protected RestaurantList doInBackground(String... url) {            
    
                publishProgress(true);         
    
                HttpGet httpget = new HttpGet(url[0]);          
    
                // Execute the request
                HttpResponse response;
                try {
                    response = httpclient.execute(httpget);
                    HttpEntity entity = response.getEntity();
    
                    if (entity != null) {
    
                        InputStream instream = entity.getContent();
    
                        Reader r = new InputStreamReader(instream);                      
    
                        Gson gson = new Gson();
                        restaurantList = gson.fromJson(r, RestaurantList.class);
    
                        int nResults = restaurantList.getSize();
    
                        if (nResults>0) {                       
    
                            lv.setVisibility(View.VISIBLE); //app crashes here                      
    
                            lv.setAdapter( new ArrayAdapter<String>(Atable.this ,android.R.layout.simple_list_item_1,restaurantList.getRestaurantNames()));
    
                            lv.setOnItemClickListener(new OnItemClickListener() {
    
                                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    
                                    Intent intent = new Intent(Atable.this, RestaurantDescription.class);
                                    Restaurant tmp_resto = restaurantList.getRestaurant((int)id);
    
                                    String tmp_categories = tmp_resto.getCategories().get(0);
                                    for (int i=1; i<tmp_resto.getCategories().size(); i++) {
                                        tmp_categories+=", "+tmp_resto.getCategories().get(i);
                                    }
    
                                    String address = tmp_resto.getStreet()+", "+tmp_resto.getStreetNumber()+"\n"+tmp_resto.getCity()+
                                                    " "+tmp_resto.getPostalCode()+"\n"+tmp_resto.getCountry();
    
                                    intent.putExtra("name", tmp_resto.getName());
                                    intent.putExtra("address", address);                                
                                    intent.putExtra("rating", tmp_resto.getRating());
                                    intent.putExtra("price_range", tmp_resto.getPriceRange());
                                    intent.putExtra("categories", tmp_categories);
                                    intent.putExtra("latitude", tmp_resto.getLatitude());
                                    intent.putExtra("longitude", tmp_resto.getLongitude());
                                    startActivityForResult(intent, ACTIVITY_EDIT);
                                }
                            });
    
    
                        }
    
                        else {
                            lv.setVisibility(View.GONE);
                            mNoresults.setVisibility(View.VISIBLE);
                        }
    
                        //Closing the input stream will trigger connection release
                        instream.close();
                    }   
    
    
                } catch (ClientProtocolException e) {                   
                    e.printStackTrace();
                } catch (IOException e) {                   
                    e.printStackTrace();
                }
    
                return restaurantList;
            }
    
            @Override
            protected void onProgressUpdate(Boolean... progress) {
                // line below coupled with 
                //    getWindow().requestFeature(Window.FEATURE_INDETERMINATE_PROGRESS) 
                //    before setContentView 
                // will show the wait animation on the top-right corner
                Atable.this.setProgressBarIndeterminateVisibility(progress[0]);
            }
    
            @Override
            protected void onPostExecute(RestaurantList result) {
                publishProgress(false);
                // Do something with result in your activity
            }
    
    
    
    
        }
    
    2 回复  |  直到 15 年前
        1
  •  1
  •   Phil    15 年前

    在Android中,所有UI更新都在主线程(也称为UI线程)上完成。当您生成一个新线程来执行耗时的任务以避免阻塞UI时,这是很好的。

    但是为了避免各种不确定的行为,UI更新总是必须在UI线程上进行。如果尝试从其他线程执行此操作,将引发异常。

    ListView 基于 nResults . 你可以试着回去 结果 doInBackground() . 它将传递给 onPostExecute() ,将在UI线程上执行。

    http://android-developers.blogspot.com/2009/05/painless-threading.html

    HTH公司

        2
  •  0
  •   Ben    15 年前

    推荐文章