2010-07-04 4 views
1

웹 서비스에서 가져온 데이터를 ListView로 설정하고 싶습니다. AsyncTask 인스턴스에서 데이터를 가져 오지만 일부 ListView 특성을 설정하려고하면 "lv.setVisibility (View.VISIBLE);"라인에서 충돌이 발생합니다. 아무도 도울 수 있니?AsyncTask 클래스에서 ListView를 설정할 때의 문제

감사

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 
     } 




    } 

답변

1

Android에서 모든 UI 업데이트는 기본 스레드 (UI 스레드라고도 함)에서 수행됩니다. UI를 차단하지 않기 위해 시간이 많이 걸리는 작업을 수행 할 새 스레드를 생성 할 때 좋습니다.

그러나 모든 종류의 불확정 동작을 피하려면 UI 스레드에서 항상 UI 업데이트를 수행해야합니다. 다른 스레드에서 그렇게하려고 시도하면 예외가 발생합니다.

예를 들어, nResults 값을 기준으로 ListView에 대해 서로 다른 업데이트를 수행하는 것을 확인했습니다. doInBackground()nResults을 반환 해보세요. onPostExecute()으로 전달되며 UI 스레드에서 실행됩니다. http://android-developers.blogspot.com/2009/05/painless-threading.html

HTH

:

당신 싶어 안드로이드의 스레드에 대한 몇 가지 유용한 정보가이 문서를 체크 아웃

0

당신은 ... 당신은 ... 미리 실행하거나 진행 업데이트 방법에 포스트에서 실행할 것을 할 필요가 doinbachground 방법에서 UI 스레드에 액세스 할 수 없습니다

관련 문제