2015-01-29 2 views
2

У меня есть ArrayList строк, который содержит до 100 000 строк и хочет сделать HTTP-запрос для получения данных для каждой строки, а затем создать и вставить его в базу данных. Я делаю это со следующим кодом прямо сейчас, но он занимает слишком много времени, и я не уверен, что задачи выполняются асинхронно. Есть ли способ сделать это быстрее?Выполнение AsyncTask на Arraylist в Android для обновления базы данных

ArrayList<String> objects = new ArrayList<String>(); 
AsyncTask<List<String>, Void, Thread> downloadBookTask = new AsyncTask<List<String>, Void, Thread>() { 
     @Override 
     protected Thread doInBackground(List<String>... params) { 

      for (String object : params[0]) { 

       HttpURLConnection conn = null; 
       try { 
        conn = NetworkManager.getHttpURLConnection(new URL(object)); 

        conn.setConnectTimeout(10000); 
        conn.connect(); 

        ByteArrayOutputStream bais = new ByteArrayOutputStream(); 
        InputStream is = null; 
        try { 
         is = conn.getInputStream(); 
         // Read 4K at a time 
         byte[] byteChunk = new byte[4096]; 
         int n; 

         while ((n = is.read(byteChunk)) > 0) { 
          bais.write(byteChunk, 0, n); 
         } 
        } catch (IOException e) { 
         //e.printStackTrace(); 
        } finally { 
         if (is != null) { 
          is.close(); 
         } 
         conn.disconnect(); 
        } 
        saveDownloadedData(object, bais.toByteArray()); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       }    } 
      return null; 
     } 
    }; 
    downloadBookTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, objects); 
} 

public void saveDownloadedData(String object, byte[] data) { 
    Book currentBook = new Book(object, data); 
    addBookToDatabase(currentBook);  
} 
+0

Исправьте меня, если я ошибаюсь, но похоже, что вы выполняете одну асинтезу для списка строк? Разве вы не хотите запускать асинтез для каждой строки в списке? – user1282637

+0

У меня был цикл for, повторяющийся через arraylist и внутри цикла for. Я создал асинтез для текущей строки, но он был еще медленнее, чем сейчас. – user2687482

+0

использовать Executors для очень длинных задач, например ExecutorService newFixedThreadPool (int nThreads) вы пропускаете int 3, для 3 потоков и выполняете 3 задачи одновременно, когда одна задача завершена, отправляет другую задачу исполнителю, после того как все ваши задачи отправляются исполнителю, запустите executor.shutdown, это сделает исполнитель не принимая новые задачи, но завершит выполнение текущих. –

ответ

2

Это медленно, потому что ваши downloadBookTask100,000 преобразования приложений HTTP соединения synchronized.

Чтобы улучшить этот код вы можете попробовать этот способ: каждые 1000 строк означают 1000 соединений HTTP, вы можете создать AsyncTask запустить его async Так вы будете иметь 100 AsyncTask запустить параллелизм, это будет в 100 раз быстрее, чем ваш путь ,

Номер AsyncTask зависит от аппаратного ОЗУ и процессора устройства, вы можете увеличить его уменьшение в соответствии с вашим случаем.

Примечание: будьте внимательны при использовании ArrayList с MultiThreading, это не threadsafe.

+0

Спасибо за ваши предложения. Я закончил тем, что делаю это так, и сейчас намного быстрее! – user2687482

+0

добро пожаловать –

0

Вы не можете улучшить свой текущий HttpRequest. Глядя на свой код, вы просто используете 1 AsyncTask, чтобы сделать 100,000 запросов. Для каждого запроса требуется, по крайней мере, 1s, поэтому он будет 100 000 с (слишком длинный). Есть некоторые способы улучшить вашу производительность:
1. Нерест 100 000 потоков. Уродливо? Не делайте этого, он уничтожит ваше приложение.
2. Использование 100 000 AsyncTask s, тоже не очень хорошая идея (нормальная функция execute, все ваши AsyncTask будут работать в одном потоке, вы можете изменить это поведение с помощью executeOnExecutor, но все равно ужасно).
3. Измените свой HttpRequest, чтобы отправить 100,000String сразу и return список объектов, которые вам нужны, с json.
Я думаю, что метод 3 - лучший способ улучшить вашу производительность, в противном случае, AFAIK, нет способа :)

+0

Изменение HttpRequest определенно будет лучшим решением, но, к сожалению, в моем случае это не вариант. Спасибо за ваши предложения. – user2687482

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