我有一个包含多达100,000个字符串的字符串ArrayList,并希望创建一个HTTP请求来获取每个字符串的数据然后创建并将其插入到数据库中。我现在使用以下代码执行此操作,但它需要太长时间,我不确定任务是异步执行的。有没有办法让这更快?
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 :(得分:2)
由于您downloadBookTask
执行100,000
http连接synchronized
,因此速度很慢。
要改进此代码,您可以尝试这种方式:每1000个字符串表示1000个http连接,您可以创建AsyncTask
来运行它async
。这样您就可以运行100 AsyncTask
并发性,它将比你的方式快100倍。
AsyncTask
的数量取决于您的设备硬件RAM和CPU,您可以增加它以适合您的情况。
注意:当ArrayList
与MultiThreading
一起使用时,请保持冷静,而不是threadsafe
。
答案 1 :(得分:0)
您目前的HttpRequest
无法改善很多。查看代码,您只需使用1 AsyncTask
来执行100,000
次请求。每个请求至少需要1s
进行连接,因此它将是100,000(太长)。有一些方法可以改善你的表现:
1。产生100,000个线程。丑陋吧?不要这样做,它会破坏你的应用程序。
2。使用100,000 AsyncTask
s,也不是一个好主意(正常execute
函数,所有AsyncTask
都将在一个线程上运行,您可以使用executeOnExecutor
更改该行为,但是仍然很糟糕)。
3。将HttpRequest
改为一次发送100,000
String
,将return
所需对象列表更改为json
。
我认为方法3是提高你表现的最好方法,否则,AFAIK,没有办法:)