2017-01-19 1 views
0

В моем приложении у меня есть две задачи async, оба из которых вызывают вызовы API.Android: моя задача async работает в потоке ui и останавливает мое приложение

Во-первых, asynctask1 попадает в конечную точку url, и я разбираю, сколько страниц для каждой категории мне нужно будет ударить моей следующей (более жесткой) асинтезной. Пример: мой первый AsyncTask получит мне массив, который выглядит как

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

Так в основном, это означает, что будет {сумма выше массива} различных конечных точек для меня, чтобы ударить, чтобы получить мои данные.

Этот массив затем проходит мимо моей asynctask2. Asynctask2 имеет два для циклов. Внешний forloop предназначен для каждой категории (для каждой буквы алфавита имеется 26 категорий, по 1 категории). Внутренний цикл for перебирает каждую страницу категории в зависимости от того, сколько страниц указано для этой категории этим массивом выше.

Я делаю что-то вроде 300 вызовов API в asynctask2. По какой-то причине это, похоже, увядает мой поток пользовательского интерфейса, хотя он должен работать в фоновом режиме.

Ниже мой код asynctask2 (ВНИМАНИЕ: Гадкий код наступить)

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; 
} 
} 

По желанию, вот как я вызова моего asynctask2

try {itemDatabase = itemDatabaseUpdater.execute(itemCatagoryNumbers).get();} catch (Exception e){} 
+1

Итак, как вы называете AsyncTask – EpicPandaForce

+0

@EpicPandaForce проверяете мое сообщение, я только что отредактировал его, чтобы показать, как я называю свою асинтезу. Спасибо –

ответ

2

Вы звоните get() на AsyncTask. Это говорит: «Свяжите текущий поток, пока задача не завершится». Поскольку текущий поток является основным потоком приложения, вы блокируете этот поток, который полностью исключает значение использования AsyncTask.

Удалите свои get() звонки. Используйте результаты своей задачи в onPostExecute(), который вызывается в главном потоке приложения, и поэтому вам безопасно обновлять свой интерфейс.

+0

Это исправило мою проблему. Спасибо! –

Смежные вопросы