2013-04-20 133 views
3

我有3個紡紗器和一個列表視圖。在第一個微調器中,用戶選擇一個狀態。然後下一個微調器就會填滿該州的所有縣。然後,用戶選擇一個縣,最後一個微調者填充該縣的城市。最後,用戶選擇一個城市,列表視圖會被該城市的醫院填充。所有這些數據都是從數據庫中提取的,並且工作正常。我遇到的問題是如果我想回去改變縣或州或城市的應用程序崩潰。Android從其他紡紗廠填充紡紗器

這是堆棧跟蹤:

04-20 23:26:33.604: E/AndroidRuntime(1781): FATAL EXCEPTION: AsyncTask #5 
04-20 23:26:33.604: E/AndroidRuntime(1781): java.lang.RuntimeException: An error occured while executing doInBackground() 
04-20 23:26:33.604: E/AndroidRuntime(1781):  at android.os.AsyncTask$3.done(AsyncTask.java:299) 
04-20 23:26:33.604: E/AndroidRuntime(1781):  at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352) 
04-20 23:26:33.604: E/AndroidRuntime(1781):  at java.util.concurrent.FutureTask.setException(FutureTask.java:219) 
04-20 23:26:33.604: E/AndroidRuntime(1781):  at java.util.concurrent.FutureTask.run(FutureTask.java:239) 
04-20 23:26:33.604: E/AndroidRuntime(1781):  at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230) 
04-20 23:26:33.604: E/AndroidRuntime(1781):  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080) 
04-20 23:26:33.604: E/AndroidRuntime(1781):  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573) 
04-20 23:26:33.604: E/AndroidRuntime(1781):  at java.lang.Thread.run(Thread.java:856) 
04-20 23:26:33.604: E/AndroidRuntime(1781): Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. 
04-20 23:26:33.604: E/AndroidRuntime(1781):  at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:4746) 
04-20 23:26:33.604: E/AndroidRuntime(1781):  at android.view.ViewRootImpl.focusableViewAvailable(ViewRootImpl.java:2588) 
04-20 23:26:33.604: E/AndroidRuntime(1781):  at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:608) 
04-20 23:26:33.604: E/AndroidRuntime(1781):  at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:608) 
04-20 23:26:33.604: E/AndroidRuntime(1781):  at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:608) 
04-20 23:26:33.604: E/AndroidRuntime(1781):  at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:608) 
04-20 23:26:33.604: E/AndroidRuntime(1781):  at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:608) 
04-20 23:26:33.604: E/AndroidRuntime(1781):  at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:608) 
04-20 23:26:33.604: E/AndroidRuntime(1781):  at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:608) 
04-20 23:26:33.604: E/AndroidRuntime(1781):  at android.view.ViewGroup.focusableViewAvailable(ViewGroup.java:608) 
04-20 23:26:33.604: E/AndroidRuntime(1781):  at android.view.View.setFlags(View.java:8405) 
04-20 23:26:33.604: E/AndroidRuntime(1781):  at android.view.View.setFocusable(View.java:5767) 
04-20 23:26:33.604: E/AndroidRuntime(1781):  at android.widget.AdapterView.checkFocus(AdapterView.java:718) 
04-20 23:26:33.604: E/AndroidRuntime(1781):  at android.widget.AdapterView$AdapterDataSetObserver.onChanged(AdapterView.java:812) 
04-20 23:26:33.604: E/AndroidRuntime(1781):  at android.database.DataSetObservable.notifyChanged(DataSetObservable.java:37) 
04-20 23:26:33.604: E/AndroidRuntime(1781):  at android.widget.BaseAdapter.notifyDataSetChanged(BaseAdapter.java:50) 
04-20 23:26:33.604: E/AndroidRuntime(1781):  at android.widget.ArrayAdapter.notifyDataSetChanged(ArrayAdapter.java:286) 
04-20 23:26:33.604: E/AndroidRuntime(1781):  at android.widget.ArrayAdapter.add(ArrayAdapter.java:182) 
04-20 23:26:33.604: E/AndroidRuntime(1781):  at com.photosbychristian.ems.Edit$LoadCity.doInBackground(Edit.java:315) 
04-20 23:26:33.604: E/AndroidRuntime(1781):  at com.photosbychristian.ems.Edit$LoadCity.doInBackground(Edit.java:1) 
04-20 23:26:33.604: E/AndroidRuntime(1781):  at android.os.AsyncTask$2.call(AsyncTask.java:287) 
04-20 23:26:33.604: E/AndroidRuntime(1781):  at java.util.concurrent.FutureTask.run(FutureTask.java:234) 
04-20 23:26:33.604: E/AndroidRuntime(1781):  ... 4 more 

04-20 23:26:43.693: E/WindowManager(1781): Activity com.photosbychristian.ems.Edit has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{b32d40f0 V.E..... R.....ID 0,0-564,230} that was originally added here 
04-20 23:26:43.693: E/WindowManager(1781): android.view.WindowLeaked: Activity com.photosbychristian.ems.Edit has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{b32d40f0 V.E..... R.....ID 0,0-564,230} that was originally added here 
04-20 23:26:43.693: E/WindowManager(1781): at android.view.ViewRootImpl.<init>(ViewRootImpl.java:354) 
04-20 23:26:43.693: E/WindowManager(1781): at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:216) 
04-20 23:26:43.693: E/WindowManager(1781): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69) 
04-20 23:26:43.693: E/WindowManager(1781): at android.app.Dialog.show(Dialog.java:281) 
04-20 23:26:43.693: E/WindowManager(1781): at com.photosbychristian.ems.Edit$LoadCity.onPreExecute(Edit.java:293) 
04-20 23:26:43.693: E/WindowManager(1781): at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:586) 
04-20 23:26:43.693: E/WindowManager(1781): at android.os.AsyncTask.execute(AsyncTask.java:534) 
04-20 23:26:43.693: E/WindowManager(1781): at com.photosbychristian.ems.Edit$LoadCounty$2.onItemSelected(Edit.java:272) 
04-20 23:26:43.693: E/WindowManager(1781): at android.widget.AdapterView.fireOnSelected(AdapterView.java:892) 
04-20 23:26:43.693: E/WindowManager(1781): at android.widget.AdapterView.access$200(AdapterView.java:49) 
04-20 23:26:43.693: E/WindowManager(1781): at android.widget.AdapterView$SelectionNotifier.run(AdapterView.java:860) 
04-20 23:26:43.693: E/WindowManager(1781): at android.os.Handler.handleCallback(Handler.java:725) 
04-20 23:26:43.693: E/WindowManager(1781): at android.os.Handler.dispatchMessage(Handler.java:92) 
04-20 23:26:43.693: E/WindowManager(1781): at android.os.Looper.loop(Looper.java:137) 
04-20 23:26:43.693: E/WindowManager(1781): at android.app.ActivityThread.main(ActivityThread.java:5039) 
04-20 23:26:43.693: E/WindowManager(1781): at java.lang.reflect.Method.invokeNative(Native Method) 
04-20 23:26:43.693: E/WindowManager(1781): at java.lang.reflect.Method.invoke(Method.java:511) 
04-20 23:26:43.693: E/WindowManager(1781): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) 
04-20 23:26:43.693: E/WindowManager(1781): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) 
04-20 23:26:43.693: E/WindowManager(1781): at dalvik.system.NativeStart.main(Native Method) 

我的代碼是:

package com.photosbychristian.ems; 

import java.util.ArrayList; 
import java.util.List; 

import org.apache.http.NameValuePair; 
import org.apache.http.message.BasicNameValuePair; 
import org.json.JSONArray; 
import org.json.JSONException; 
import org.json.JSONObject; 

import android.app.ListActivity; 
import android.app.ProgressDialog; 
import android.os.AsyncTask; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.View; 
import android.widget.AdapterView; 
import android.widget.ArrayAdapter; 
import android.widget.ListView; 
import android.widget.Spinner; 
import android.widget.TabHost; 
import android.widget.TabHost.TabSpec; 

public class Edit extends ListActivity { 

private ProgressDialog stateDialog; 
private ProgressDialog countyDialog; 
private ProgressDialog cityDialog; 
private ProgressDialog hospitalDialog; 

JSONParser stateParser = new JSONParser(); 
JSONParser countyParser = new JSONParser(); 
JSONParser cityParser = new JSONParser(); 
JSONParser hospitalParser = new JSONParser(); 

private static String url_state = "http://www.photosbychristian.com/ems/states.php"; 
private static String url_county = "http://www.photosbychristian.com/ems/countys.php"; 
private static String url_city = "http://www.photosbychristian.com/ems/citys.php"; 
private static String url_hospital = "http://www.photosbychristian.com/ems/hospitals.php"; 

private static final String TAG_STATE_DISPLAY = "display"; 
private static final String TAG_COUNTY_DISPLAY = "display"; 
private static final String TAG_CITY_DISPLAY = "display"; 
private static final String TAG_HOSPITAL_DISPLAY = "display"; 

JSONArray statesArray = null; 
JSONArray countysArray = null; 
JSONArray citysArray = null; 
JSONArray hospitalArray = null; 

ArrayAdapter<String> stateAdapter; 
ArrayAdapter<String> countyAdapter; 
ArrayAdapter<String> cityAdapter; 
ArrayAdapter<String> hospitalAdapter; 

Spinner state; 
Spinner county; 
Spinner city; 

String stateLabel; 
String cityLabel; 
String hospitalLabel; 
ListView hosps; 
ArrayList<String> hosp = new ArrayList<String>(); 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    // TODO Auto-generated method stub 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.edit); 

    TabHost th = (TabHost) findViewById(R.id.tabhost); 
    th.setup(); 
    TabSpec specs = th.newTabSpec("tag1"); 
    specs.setContent(R.id.tab1); 
    specs.setIndicator("My Hospitals"); 
    th.addTab(specs); 
    specs = th.newTabSpec("tag2"); 
    specs.setContent(R.id.tab2); 
    specs.setIndicator("Add Hospitals"); 
    th.addTab(specs); 
    new LoadStates().execute(); 

    state = (Spinner) findViewById(R.id.sState); 
    county = (Spinner) findViewById(R.id.sCounty); 
    city = (Spinner) findViewById(R.id.sCity); 
    hosps = getListView(); 

    stateAdapter = new ArrayAdapter<String>(this, 
      android.R.layout.simple_spinner_item); 
    countyAdapter = new ArrayAdapter<String>(this, 
      android.R.layout.simple_spinner_item); 
    cityAdapter = new ArrayAdapter<String>(this, 
      android.R.layout.simple_spinner_item); 
    hospitalAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, hosp); 

} 

class LoadStates extends AsyncTask<String, String, String> { 

    // Before starting background thread Show State Progress Dialog 

    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
     stateDialog = new ProgressDialog(Edit.this); 
     stateDialog.setMessage("Loading States. Please wait..."); 
     stateDialog.setIndeterminate(false); 
     stateDialog.setCancelable(false); 
     stateDialog.show(); 
    } 

    /** Get states form Internet **/ 

    protected String doInBackground(String... args) { 
     // Building Parameters 
     List<NameValuePair> params = new ArrayList<NameValuePair>(); 
     // getting JSON string from URL 
     JSONObject json = stateParser.makeHttpRequest(url_state, "GET", 
       params); 

     // Check your log cat for JSON response 
     Log.d("All States: ", json.toString()); 

     stateAdapter 
       .setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 
     stateAdapter.add("Select A State"); 
     try { 
      // products found 
      // Getting Array of Products 
      statesArray = json.getJSONArray("states"); 

      // looping through All Products 
      for (int i = 0; i < statesArray.length(); i++) { 
       JSONObject c = statesArray.getJSONObject(i); 

       // Storing each JSON item in variable 
       // String id = c.getString(TAG_HID); 
       String disp = c.getString(TAG_STATE_DISPLAY); 

       stateAdapter.add(disp); 

      } 

     } catch (JSONException e) { 
      e.printStackTrace(); 
     } 

     return null; 
    } 

    /** After completing background task Dismiss the progress dialog **/ 

    protected void onPostExecute(String file_url) { 
     // dismiss the dialog after getting all products 
     stateDialog.dismiss(); 
     // updating UI from Background Thread 
     runOnUiThread(new Runnable() { 
      public void run() { 
       // add states to spinner 
       state.setAdapter(stateAdapter); 

      } 
     }); 

     state.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { 
      public void onItemSelected(AdapterView<?> parent, View view, 
        int position, long id) { 
       // On selecting a spinner item 
       String label = parent.getItemAtPosition(position) 
         .toString(); 
       if (label == "Select A State") { 

       } else { 
        stateLabel = label; 
        // load county spinner 

        new LoadCounty().execute(); 
       } 
      } 

      public void onNothingSelected(AdapterView<?> arg0) { 
       // TODO Auto-generated method stub 

      } 
     }); 
    } 
} 

class LoadCounty extends AsyncTask<String, String, String> { 
    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
     countyDialog = new ProgressDialog(Edit.this); 
     countyDialog.setMessage("Loading Countys. Please wait..."); 
     countyDialog.setIndeterminate(false); 
     countyDialog.setCancelable(false); 
     countyDialog.show(); 
    } 

    // Get states form Internet 
    @Override 
    protected String doInBackground(String... args) { 
     // TODO Auto-generated method stub 
     // Building Parameters 
     List<NameValuePair> Countyparams = new ArrayList<NameValuePair>(); 
     Countyparams.add(new BasicNameValuePair("state", stateLabel)); 
     // getting JSON string from URL 
     JSONObject Countyjson = countyParser.makeHttpRequest(url_county, 
       "GET", Countyparams); 

     // Check your log cat for JSON response 
     Log.d("All Countys: ", Countyjson.toString()); 

     countyAdapter 
       .setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 
     countyAdapter.add("Select A County"); 
     try { 
      // products found 
      // Getting Array of Products 
      countysArray = Countyjson.getJSONArray("county"); 

      // looping through All Products 
      for (int i = 0; i < countysArray.length(); i++) { 
       JSONObject c = countysArray.getJSONObject(i); 

       // Storing each JSON item in variable 
       // String id = c.getString(TAG_HID); 
       String disp = c.getString(TAG_COUNTY_DISPLAY); 

       countyAdapter.add(disp); 

      } 

     } catch (JSONException e) { 
      e.printStackTrace(); 
     } 

     return null; 
    } 

    // After completing background task Dismiss the progress dialog 

    protected void onPostExecute(String file_url) { 
     // dismiss the dialog after getting all products 
     countyDialog.dismiss(); 
     // updating UI from Background Thread 
     runOnUiThread(new Runnable() { 
      public void run() { 
       // add states to spinner 
       county.setAdapter(countyAdapter); 

      } 
     }); 

     county.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { 
      public void onItemSelected(AdapterView<?> parent, View view, 
        int position, long id) { 
       // On selecting a spinner item 
       String label = parent.getItemAtPosition(position) 
         .toString(); 
       if (label == "Select A County") { 

       } else { 
        // load city spinner 
        hospitalAdapter.clear(); 
        hospitalAdapter.notifyDataSetChanged(); 
        cityAdapter.clear(); 
        cityAdapter.notifyDataSetChanged(); 
        cityLabel = label; 
        new LoadCity().execute(); 

       } 
      } 

      public void onNothingSelected(AdapterView<?> arg0) { 
       // TODO Auto-generated method stub 

      } 
     }); 
    } 
} 

class LoadCity extends AsyncTask<String, String, String> { 
    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
     cityDialog = new ProgressDialog(Edit.this); 
     cityDialog.setMessage("Loading Citys. Please wait..."); 
     cityDialog.setIndeterminate(false); 
     cityDialog.setCancelable(false); 
     cityDialog.show(); 


    } 

    // Get states form Internet 
    @Override 
    protected String doInBackground(String... args) { 
     // TODO Auto-generated method stub 
     // Building Parameters 
     List<NameValuePair> Cityparams = new ArrayList<NameValuePair>(); 
     Cityparams.add(new BasicNameValuePair("state", stateLabel)); 
     Cityparams.add(new BasicNameValuePair("county", cityLabel)); 
     // getting JSON string from URL 
     JSONObject Cityjson = cityParser.makeHttpRequest(url_city, "GET", 
       Cityparams); 

     // Check your log cat for JSON response 
     Log.d("All Citys: ", Cityjson.toString()); 

     cityAdapter 
       .setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 
     cityAdapter.add("Select A City"); 
     try { 
      // products found 
      // Getting Array of Products 
      citysArray = Cityjson.getJSONArray("city"); 

      // looping through All Products 
      for (int i = 0; i < citysArray.length(); i++) { 
       JSONObject c = citysArray.getJSONObject(i); 

       // Storing each JSON item in variable 
       // String id = c.getString(TAG_HID); 
       String disp = c.getString(TAG_CITY_DISPLAY); 

       cityAdapter.add(disp); 

      } 

     } catch (JSONException e) { 
      e.printStackTrace(); 
     } 

     return null; 
    } 

    // After completing background task Dismiss the progress dialog 

    protected void onPostExecute(String file_url) { 
     // dismiss the dialog after getting all products 
     cityDialog.dismiss(); 
     // updating UI from Background Thread 
     runOnUiThread(new Runnable() { 
      public void run() { 
       // add states to spinner 
       city.setAdapter(cityAdapter); 

      } 
     }); 

     city.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { 
      public void onItemSelected(AdapterView<?> parent, View view, 
        int position, long id) { 
       // On selecting a spinner item 
       String label = parent.getItemAtPosition(position) 
         .toString(); 

       hospitalLabel = label; 
       if (label == "Select A City") { 

       } else { 
        // load hospitals 

        new LoadHospitals().execute(); 
       } 
      } 

      public void onNothingSelected(AdapterView<?> arg0) { 
       // TODO Auto-generated method stub 

      } 
     }); 
    } 
} 

class LoadHospitals extends AsyncTask<String, String, String> { 
    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
     hospitalDialog = new ProgressDialog(Edit.this); 
     hospitalDialog.setMessage("Loading Hospitals. Please wait..."); 
     hospitalDialog.setIndeterminate(false); 
     hospitalDialog.setCancelable(false); 
     hospitalDialog.show(); 
     hospitalAdapter.clear(); 
     hospitalAdapter.notifyDataSetChanged(); 
    } 

    // Get states form Internet 
    @Override 
    protected String doInBackground(String... args) { 
     // TODO Auto-generated method stub 
     // Building Parameters 
     List<NameValuePair> hospitalparams = new ArrayList<NameValuePair>(); 
     hospitalparams.add(new BasicNameValuePair("state", stateLabel)); 
     hospitalparams.add(new BasicNameValuePair("county", cityLabel)); 
     hospitalparams.add(new BasicNameValuePair("city", hospitalLabel)); 
     // getting JSON string from URL 
     JSONObject Cityjson = hospitalParser.makeHttpRequest(url_hospital, "GET", 
       hospitalparams); 

     // Check your log cat for JSON response 
     Log.d("All Hospital: ", Cityjson.toString()); 


     try { 
      // products found 
      // Getting Array of Products 
      hospitalArray = Cityjson.getJSONArray("hospital"); 

      // looping through All Products 
      for (int i = 0; i < hospitalArray.length(); i++) { 
       JSONObject c = hospitalArray.getJSONObject(i); 

       // Storing each JSON item in variable 
       // String id = c.getString(TAG_HID); 
       String disp = c.getString(TAG_HOSPITAL_DISPLAY); 
       hosp.add(disp); 
      } 

     } catch (JSONException e) { 
      e.printStackTrace(); 
     } 

     return null; 
    } 

    // After completing background task Dismiss the progress dialog 

    protected void onPostExecute(String file_url) { 
     // dismiss the dialog after getting all products 
     hospitalDialog.dismiss(); 
     // updating UI from Background Thread 
     runOnUiThread(new Runnable() { 
      public void run() { 
       // display hospitals 
       setListAdapter(hospitalAdapter); 
       hospitalAdapter.notifyDataSetChanged(); 

      } 
     }); 
    } 
} 

} 

回答

0

你必須在UI線程,即在onPostExecute方法上管理你的stateAdapter

AsyncTaskResult設置爲包含應添加到微調器中的數據的字符串列表,然後使用您收到的列表作爲參數填充onPostExecute中的微調器。