turtleboy
turtleboy

Reputation: 7572

AsyncTask not populating ArrayList

I've an app that calls a webservice which returns an xml String. The following class processes that String and puts the required data into an ArrayList. The ArrayList is of type TwoDimentionalArrayList. Ill post these 2 classes below. They both work fine.

public class RetrieveExtraDetails {

    private static final String TAG = RetrieveExtraDetails.class.getSimpleName();
    DocumentBuilderFactory builderFactory;
    DocumentBuilder builder;
    Document document;
    TwoDimentionalArrayList<String> arrayList;


    public RetrieveExtraDetails() {
        super();
        arrayList = new TwoDimentionalArrayList<String>();
        builderFactory = DocumentBuilderFactory.newInstance();
        document = null;
        try {
            builder = builderFactory.newDocumentBuilder();
            Log.e(TAG, "built the dom factory");
        } catch (ParserConfigurationException e) {
            e.printStackTrace();  
        }

    }// end of constructor


public  TwoDimentionalArrayList<String> getExtraDetails(String xmlStr){

    ArrayList<String> array = null;

        try {

            document = builder.parse( new InputSource(new StringReader(xmlStr))); 
            Log.e(TAG, "document = " + document);

        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        Element rootElement = document.getDocumentElement();
        NodeList nodes = rootElement.getChildNodes();

        Node rota = nodes.item(0);
        NodeList callList = rota.getChildNodes();

        for(int i = 0; i < callList.getLength(); i++){

            Node call = callList.item(i);
            NodeList callChildrenList = call.getChildNodes();
            array = new ArrayList<String>();

        for(int j = 0; j < callChildrenList.getLength(); j++){

                Node callChild = callChildrenList.item(j);

                if(callChild.getNodeName().equalsIgnoreCase("RecTypeID")){
                      String nodeData =  callChild.getTextContent();
                      Log.e(TAG, "RecTypeID = " + nodeData);
                      array.add(nodeData);

                }else if (callChild.getNodeName().equalsIgnoreCase("RecType")){

                    String nodeData =  callChild.getTextContent();
                      Log.e(TAG, "RecType = " + nodeData);
                      array.add(nodeData);
                }else if (callChild.getNodeName().equalsIgnoreCase("Name")){

                    String nodeData =  callChild.getTextContent();
                      Log.e(TAG, "Name = " + nodeData);
                      array.add(nodeData);
                }else if (callChild.getNodeName().equalsIgnoreCase("Relationship")){

                    String nodeData =  callChild.getTextContent();
                      Log.e(TAG, "Relationship = " + nodeData);
                      array.add(nodeData);
                }else if (callChild.getNodeName().equalsIgnoreCase("Address")){

                    String nodeData =  callChild.getTextContent();
                      Log.e(TAG, "Address = " + nodeData);
                      array.add(nodeData);
                }else if (callChild.getNodeName().equalsIgnoreCase("Postcode")){

                    String nodeData =  callChild.getTextContent();
                      Log.e(TAG, "Postcode = " + nodeData);
                      array.add(nodeData);
                }else if (callChild.getNodeName().equalsIgnoreCase("TelNo")){

                    String nodeData =  callChild.getTextContent();
                      Log.e(TAG, "TelNo = " + nodeData);
                      array.add(nodeData);
                }else if (callChild.getNodeName().equalsIgnoreCase("Keysafe")){

                    String nodeData =  callChild.getTextContent();
                      Log.e(TAG, "Keysafe = " + nodeData);
                      array.add(nodeData);
                }else if (callChild.getNodeName().equalsIgnoreCase("Notes")){

                    String nodeData =  callChild.getTextContent();
                      Log.e(TAG, "Notes = " + nodeData);
                      array.add(nodeData);
                }else if (callChild.getNodeName().equalsIgnoreCase("Meds")){

                    String nodeData =  callChild.getTextContent();
                      Log.e(TAG, "Meds = " + nodeData);
                      array.add(nodeData);
                }



            }// end of j loop
        arrayList.add(i, array);
        }//end of i loop

        return arrayList;

    }//end of getExtraDetails



}//end of class

.

public class TwoDimentionalArrayList<T> extends ArrayList<ArrayList<T>> {

    private static final long serialVersionUID = 1L;

    public void addToInnerArray(int index, T element) {
        while (index >= this.size()) {
            this.add(new ArrayList<T>());
        }
        this.get(index).add(element);
    }

    public void addToInnerArray(int index, int index2, T element) {
        while (index >= this.size()) {
            this.add(new ArrayList<T>());
        }

        ArrayList<T> inner = this.get(index);
        while (index2 >= inner.size()) {
            inner.add(null);
        }

        inner.set(index2, element);
    }
}

Now in the following class i have an ArrayList which is set at class scope. The following class should populate this arrayList with the results from the AsyncTask. In onPostExecute the array has a size of 4 but when i logg out the value of the class scope array, it's 0 after being set by the AsyncTask. I've even call .get() on the Async to ensure that the activity wait for the result from Async before resuming execution.

Any Ideas why this ArrayList is not being populated? I've asked a similar question, but in this one i've cut the code down to make it easier to understand the problem. thanks.

ArrayList<ArrayList<String>> array;

.

public class GetRotaDetails extends NfcBaseActivity{



    ArrayList<ArrayList<String>> array;

    private static final String TAG = GetRotaDetails.class.getSimpleName();
    NfcScannerApplication nfcscannerapplication;
    String callID;
    ListView listView;
    Intent intent;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

         //set titlebar to carer's name
        nfcscannerapplication = (NfcScannerApplication) getApplication();
        intent = this.getIntent();
        Cursor cursorCarerName = nfcscannerapplication.loginValidate.queryAllFromCarer();
        cursorCarerName.moveToLast();
        String carerTitleName = cursorCarerName.getString(cursorCarerName
                .getColumnIndex(LoginValidate.C_CARER_NAME));
        setTitle(carerTitleName + " is currently logged in");


        array = new  ArrayList<ArrayList<String>>();

        listView = (ListView) findViewById(R.id.getrotadetailslistview);
        setContentView(R.layout.getrotadetailslayout);


        callID = intent.getStringExtra("callIDExtra");
        String[] params = { callID };

        AsyncGetRotaDetails agrd = new AsyncGetRotaDetails();
        try {
            agrd.execute(params).get();
        }  catch (Exception e) {
            e.printStackTrace();
        }


        Log.e(TAG, "array size = " + array.size());



    }// end of onCreate



    private class AsyncGetRotaDetails extends AsyncTask<String, Void, String> {

        ProgressDialog progressDialog;
        String rotaDetails = null;

        @Override
        protected void onPreExecute() {
            progressDialog = ProgressDialog
                    .show(GetRotaDetails.this, "Connecting to Server",
                            " retrieving rota details...", true);

        };

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

            try {
                Log.e(TAG, "inside doInBackground");

                rotaDetails = nfcscannerapplication.loginWebservice.getRotaDetail(params[0]);

            } catch (Exception e) {

                e.printStackTrace();

            }
            return rotaDetails;

        }

        @Override
        protected void onPostExecute(String xmlResult) {
            super.onPostExecute(xmlResult);
            if (progressDialog != null)
                progressDialog.dismiss();

                RetrieveExtraDetails red = new RetrieveExtraDetails();
                array = red.getExtraDetails(xmlResult);
                Log.e(TAG, "array from WS = " + array.size());


        }// end of postExecute

    }//end of Async


}

Upvotes: 0

Views: 350

Answers (1)

olshevski
olshevski

Reputation: 5010

My guess was right. AsyncTask.get() method may return result after doInBackground() method finishes, but before onPostExecute() method starts. So, technically, your array may be still empty at that point.

Also, it is very strange to launch a background thread and block the main one. What's the point?

Upvotes: 2

Related Questions