0

In my app I have two async tasks, both of which make API calls.

First, asynctask1 hits a url endpoint, and I parse out how many pages for each category I will need to hit with my next (beefier) asynctask. Ex: my first asynctask will get me an array that looks like

int[] arr = {1,5,12,40,1,0,40...,6}

So basically, that means there would be {sum of above array} different endpoints for me to hit to get my data.

This array then gets past to my asynctask2. Asynctask2 has two for loops. The outer forloop is for each category (there are 26 categories, 1 category for each letter of the alphabet). The inner for loop goes over each page of the category according to how many pages are listed for that category by that array above.

I'm making something like 300 API calls in asynctask2. For some reason this seems to be bogging down my UI thread, even though it should be running in the background.

Below is my code for asynctask2 (WARNING: Ugly code to ensue)

public class ItemDatabaseUpdater extends AsyncTask<ArrayList<Integer>, Void, ArrayList<Item>> {

private String apiRoute = "http://services.runescape.com/m=itemdb_oldschool/api/catalogue/items.json?category=1&alpha=";
private String apiLetter = "b";
private String apiRoutePage = "&page=";
private String apiPageNumber = "1";
private String data;
private ArrayList<Item> itemDB = new ArrayList<>();
private JSONParser jsonParser = new JSONParser();
private JSONArray jsonArray;
private String[] alphabet = {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n",
        "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"};
private Item _item;

protected void onPreExecute() {}

protected ArrayList<Item> doInBackground(ArrayList<Integer>... args) {
    ArrayList<Integer> pageNumbersForEachLetter = getTotalPageCountForEachLetter(args[0]);
    for (int i=0; i<pageNumbersForEachLetter.size(); i++){
        apiLetter = alphabet[i];
        for (int j=1; j<pageNumbersForEachLetter.get((i))+1; j++){
            apiPageNumber = String.valueOf(j);
            try {
                String endRoute = apiRoute + apiLetter + apiRoutePage + apiPageNumber;
                URL url = new URL(endRoute);
                HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
                try {
                    BufferedReader br = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
                    StringBuilder stringBuilder = new StringBuilder();
                    String dataEntry;
                    while ((dataEntry = br.readLine()) != null) {
                        stringBuilder.append(dataEntry).append("\n");
                    }
                    br.close();
                    data = stringBuilder.toString();

                    jsonArray = jsonParser.extractArrayFromObject(data, "items");
                    for(int k=0; k<jsonArray.length(); k++) {
                        JSONObject obj = jsonParser.extractObjectFromArray(jsonArray, k);
                        JSONObject currentDataObj = jsonParser.extractObjectFromObject(obj, "current");
                        JSONObject todayDataObj = jsonParser.extractObjectFromObject(obj, "today");
                        _item = new Item();
                        _item.setIconUrl(jsonParser.extractValueFromObject(obj,"icon"));
                        _item.setId(jsonParser.extractValueFromObject(obj,"id"));
                        _item.setName(jsonParser.extractValueFromObject(obj,"name"));
                        _item.setCurrentPrice(jsonParser.extractValueFromObject(currentDataObj,"price"));
                        _item.setPriceChangeToday(jsonParser.extractValueFromObject(todayDataObj,"price"));
                        _item.setTrendToday(jsonParser.extractValueFromObject(todayDataObj,"trend"));
                        itemDB.add(_item);
                    }
                }
                finally{
                    urlConnection.disconnect();
                }
            }
            catch (Exception e){return null;}
        }
    }
    return itemDB;
}

protected void onPostExecute(ArrayList<String> response) {}

private ArrayList<Integer> getTotalPageCountForEachLetter(ArrayList<Integer> arg){
    ArrayList<Integer> retArr = new ArrayList<>();
    for (int i : arg){
        retArr.add((int)(Math.ceil(i/12)));
    }
    return retArr;
}
}

Per request, here is how I call my asynctask2

try {itemDatabase = itemDatabaseUpdater.execute(itemCatagoryNumbers).get();} catch (Exception e){}
Josh Beckwith
  • 1,432
  • 3
  • 20
  • 38

1 Answers1

3

You are calling get() on the AsyncTask. This says "tie up the current thread until the task completes". Since your current thread is the main application thread, you are blocking that thread, which completely eliminates the value of using AsyncTask in the first place.

Remove your get() calls. Use the results of your task in onPostExecute(), which is called on the main application thread, and so it is safe for you to update your UI there.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491