3

我有 3 个微调器和一个列表视图。在第一个微调器中,用户选择一个状态。然后下一个微调器将填充该州的所有县。然后用户选择一个县,最后一个微调器将填充该县的城市。最后,用户选择了一个城市,列表视图中填充了该城市的医院。所有这些数据都是从数据库中提取的,并且工作正常。我遇到的问题是,如果我想返回并更改应用程序崩溃的县、州或城市。

这是堆栈跟踪:

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();

            }
        });
    }
}

}
4

1 回答 1

0

你必须stateAdapter在 UI 线程上管理你的,即在onPostExecute方法中。

将 的 设置为Result包含AsyncTask应添加到微调器的数据的字符串列表,然后onPostExecute使用您作为参数收到的列表填充微调器。

于 2013-04-21T00:35:55.030 回答