无法从异步任务填充listview

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

标签: android listview asynchronous methods arraylist

我有一项活动,我必须填写列表视图。活动发布到网址并接收JSON作为响应。我已经解析了JSON以在列表视图中显示,但列表视图没有被填充。

活动的完整代码:

public class RegisterFirstActivity extends ListActivity {

    private static final String TAG_CODE = "Code";
    private static final String TAG_ID = "Id";
    private static final String TAG_LAT = "Lat";
    private static final String TAG_LON = "Lon";
    private static final String TAG_NAME = "Name";


    static String response_str=null;
    static String response_code=null;





    String ac_code;
    String ac_id;
    String ac_lat;
    String ac_lon;
    String ac_name;




    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_register_first);
        sendPostRequest();
    }

    //sending async post request---------------------------------------------------------------------------------------
    private void sendPostRequest() {

        class SendPostReqAsyncTask extends AsyncTask<String, Void, String>{

            @Override
            protected String doInBackground(String... params) {



                String result = "";
                HttpClient hc = new DefaultHttpClient();
                String message;

                //HttpPost p = new HttpPost("http://192.168.1.60/tr/MobileService/GetAC");
                HttpPost p = new HttpPost("http://bumba27.byethost16.com/xxxxxxx/");
                JSONObject object = new JSONObject();
                try {

                    //object.put("Id",deviceid);
                    //object.put("StringValue",value);
//                  object.put("last_name", lastname);
//                  object.put("first_name", firstname);
//                  object.put("email", email);

                } catch (Exception ex) {

                }

                try {
                message = object.toString();


                p.setEntity(new StringEntity(message, "UTF8"));
                p.setHeader("Content-type", "application/json");
                    HttpResponse resp = hc.execute(p);
                    response_code=""+ resp.getStatusLine().getStatusCode();
                    Log.d("Response Code: ", "" + response_code);


                        InputStream inputStream = resp.getEntity().getContent();
                        InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
                        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
                        StringBuilder stringBuilder = new StringBuilder();
                        String bufferedStrChunk = null;

                        while((bufferedStrChunk = bufferedReader.readLine()) != null){
                            stringBuilder.append(bufferedStrChunk);
                        }

                        response_str= stringBuilder.toString();
                        parse_json_str(response_str);

                    if (resp != null) {
                        if (resp.getStatusLine().getStatusCode() == 204)
                            result = "true";

                        makeAToast("Response: "+resp.toString());
                    }


                    Log.d("Status line", "" + resp.getStatusLine().getStatusCode());
                } catch (Exception e) {
                    e.printStackTrace();
                    Log.i("Error in response: ",e.getMessage());

                }

                return result;              

            }

            @Override
            protected void onPostExecute(String result) {
                super.onPostExecute(result);

                //Toast.makeText(getApplicationContext(), result, Toast.LENGTH_LONG).show();

                //writeToFile(result, "record.txt");

                Log.i("RESPONSE",result);


            }           
        }

        SendPostReqAsyncTask sendPostReqAsyncTask = new SendPostReqAsyncTask();
        sendPostReqAsyncTask.execute();     
    }


    //-----------------------------------------------------------------------------------------------


    public void parse_json_str(String json_str)
    {
        // Hashmap for ListView
        ArrayList<HashMap<String, String>> contactList = new ArrayList<HashMap<String, String>>();



        JSONArray lJSONArray;
        String jString = json_str;
        try
        {
            lJSONArray = new JSONArray( jString );

            JSONObject lJSONObject;
            for ( int i = 0; i < lJSONArray.length(); i++ )
            {
                lJSONObject = lJSONArray.getJSONObject( i );
                // PARSE FIELD HERE
                ac_code = lJSONObject.getString( TAG_CODE );
                Log.i("Code: ",ac_code);
                ac_id=lJSONObject.getString( TAG_ID );
                Log.i("Id: ",ac_id);
                ac_lat=lJSONObject.getString( TAG_LAT );
                Log.i("Lat: ",ac_lat);
                ac_lon=lJSONObject.getString( TAG_LON );
                Log.i("Lon: ",ac_lon);
                ac_name=lJSONObject.getString( TAG_NAME );
                Log.i("Name: ",ac_name);
                // ETC

             // creating new HashMap
                HashMap<String, String> map = new HashMap<String, String>();

                // adding each child node to HashMap key => value
                map.put(TAG_CODE, ac_code);
                map.put(TAG_ID, ac_id);
                map.put(TAG_LAT, ac_lat);
                map.put(TAG_LON, ac_lon);
                map.put(TAG_NAME, ac_name);
                Log.d("map","haeflloter putting");
                Log.d("map",map+"");
                // adding HashList to ArrayList
                contactList.add(map);
                //Log.d("tag name", contactList+"");

            }







                        /**
                         * Updating parsed JSON data into ListView
                         * */
                        ListAdapter adapter = new SimpleAdapter(this, contactList,R.layout.list_item,new String[] { TAG_NAME }, new int[] {R.id.name});
                        Log.d("tag name", contactList+"");
                        setListAdapter(adapter);


        }
        catch( Exception e )
        {
            Log.d("catch", e+"");
        }




    }








    public void makeAToast(String str) {
        //yet to implement
        Toast toast = Toast.makeText(this,str, Toast.LENGTH_SHORT);
        toast.setGravity(Gravity.CENTER, 0, 0);
        toast.show();
    }
} 

布局文件activity_register_first:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical">
    <!-- Main ListView 
         Always give id value as list(@android:id/list)
    -->
    <ListView
        android:id="@android:id/list"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"/>

</LinearLayout>

list_item.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">  
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">
        <!-- Name Label -->
        <TextView
            android:id="@+id/name"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:textColor="#43bd00"
            android:textSize="16sp"
            android:textStyle="bold"
            android:paddingTop="6dip"
            android:paddingBottom="2dip" />
        <!-- Description label -->


    </LinearLayout>

</LinearLayout>

我得到的错误是:

02-15 19:26:46.154: D/catch(1429): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

我已经按照this教程查看了列表视图。

我哪里错了?如何解决这个问题?

2 个答案:

答案 0 :(得分:3)

在AsyncTask中,只有onPreExecute()onProgressUpdate()onPostExecute()在UI线程中执行。

doInBackground()在后​​台线程中执行。

您应该存储来自doInBackground()的数据,然后在onPostExecute()更新您的用户界面。

修改

使您的contactList成为您的AsyncTask的成员,并添加此代码(未经测试):

protected void onPostExecute(String result) {
    super.onPostExecute(result);

    if(mContactList != null) {      
        ListAdapter adapter = new SimpleAdapter(this, contactList,R.layout.list_item,new String[] { TAG_NAME }, new int[] {R.id.name});
        Log.d("tag name", contactList+"");
        setListAdapter(adapter);
    }

    Log.i("RESPONSE",result);
} 

答案 1 :(得分:1)

UI更改必须在UI线程中完成。这就是onPostExecute()的用途,它在UI线程中运行。