lord_sneed
lord_sneed

Reputation: 824

Android: Async Thread Issue

I have an app that is loading data from text files and storing the data from each file into a separate ArrayList. I was told to load the data on an async thread even though my app does not crash loading it all from the onCreate method (it just takes approx 12 seconds to load all of the data from the text files into the ArrayLists).

I have attempted to set up an async thread, but I have run into an issue. I am brand new to async threads, so I do not know/yet fully understand all of the details (I am trying to piece info together from different sources). Here is the relevent code:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_name);

    new loadData().execute();

    arrayListElement = ArrayList1.get(0);

}

private class loadData extends AsyncTask<Void, Void, Void> {

    ProgressDialog dialog;
    protected void onPreExecute() {
        dialog = new ProgressDialog(ClassName.this);
        dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        dialog.show();
    }

    @Override
    protected Void doInBackground(Void... arg0) {
    // TODO Auto-generated method stub
        populateArrayLists();
        return null;
    }

    /*protected void onProgressUpdate() {

    }

    protected void onPostExecute() {

    }*/

}

I am getting an IndexOutOfBoundsException (invalid index 0, size is 0) at the last statement in the onCreate method.

All I want to do is load the data on a separate thread because even though my app does not crash, I was told I should do it. The UI thread should handle all of the rest. The app was working fine until I added the async thread code.

How my files are read can be seen here: Android: Asynch Thread Needed?

What am I doing wrong?

Upvotes: 0

Views: 243

Answers (2)

LuxuryMode
LuxuryMode

Reputation: 33771

You are returning null from doInBackground, so of course this all fails. Use the AsyncTask for what it's meant to do. To get it to work correctly, you need to correctly define your AsyncTask with the appropriate type paramaters.

Instead of making populateArrayLists have side effects of updating some other field, have a method like:

void List<Foo> getListOfFoo() {
  ArrayList<Foo> listOfFoos = getTheListSomehow();
  return listOfFoos;
}

For example:

    public class MyActivity extends Activity {


        public void doSomething(List<String> stringList) {
           //do something here

        }

        class MyAsyncTask extends AsyncTask<Void, Void, List<String>> {

            @Override
            protected List<String> doInBackground(Void... params) {
                ArrayList<String> listOfStrings = getListOfStrings();
                return listOfStrings;
            }

            @Override
            protected void onPostExecute(List<String> strings) {
                super.onPostExecute(strings);
                doSomething(strings);
            }

            private List<String> getListOfStrings() {
ArrayList<String> stringList = new ArrayList<String>();
                //This is where you'd actually perform your expensive operation
  BufferedReader br = null;
    try {
        br = new BufferedReader(new InputStreamReader(getAssets().open(
                "text1.txt")));
        String text;
        while ((word = br.readLine()) != null) {
            stringList.add(text);
        }                           
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            br.close(); // stop reading
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
                return stringList;
            }
        }
    }

Upvotes: 1

NaviRamyle
NaviRamyle

Reputation: 4007

AsyncTask is not yet done running, that's why arrayListElement = ArrayList1.get(0); is having an IndexOutOfBoundsException.

Try This

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_name);

    new loadData().execute();
}

private class loadData extends AsyncTask<Void, Void, Void> {

    ProgressDialog dialog;
    protected void onPreExecute() {
        dialog = new ProgressDialog(ClassName.this);
        dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        dialog.show();
    }

    @Override
    protected Void doInBackground(Void... arg0) {
    // TODO Auto-generated method stub
        populateArrayLists();
        return null;
    }

    protected void onPostExecute(Void result) {
        arrayListElement = ArrayList1.get(0);
        dialog.dismiss();
        super.onPostExecute(result);
    }

}

Upvotes: 2

Related Questions