在 Android 中的 Arraylist 上执行 AsyncTask 以更新数据库
Execute AsyncTask on Arraylist in Android to Update database
我有一个包含多达 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);
}
它很慢,因为你的 downloadBookTask
执行 100,000
http 连接 synchronized
。
要改进此代码,您可以这样尝试:每 1000 个字符串表示 1000 个 http 连接,您可以创建一个 AsyncTask
到 运行 它 async
。所以您将有 100 个AsyncTask
运行并发,比你的方式快100倍
AsyncTask
的数量取决于您的设备硬件 RAM 和 CPU,您可以增加或减少它以适应您的情况。
注意:当您将 ArrayList
与 MultiThreading
一起使用时请注意,它不是 threadsafe
。
您目前的 HttpRequest
并不能提高多少。查看您的代码,您只需使用 1 AsyncTask
来执行 100,000
请求。每个请求至少需要 1s
连接,所以这将是 100,000s(太长)。有一些方法 2 可以提高你的表现:
1。生成 100,000 个线程。丑吧?不要那样做,它会破坏你的应用程序。
2。使用 100,000 个 AsyncTask
s,也不是一个好主意(正常的 execute
函数,你所有的 AsyncTask
将在单个线程上 运行,你可以使用 [=17 更改该行为=],但仍然很糟糕)。
3。将您的 HttpRequest
更改为立即发送 100,000
String
和 return
您需要的对象列表 json
。
我认为方法 3 是提高性能的最佳方法,否则,AFAIK,没有办法:)
我有一个包含多达 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);
}
它很慢,因为你的 downloadBookTask
执行 100,000
http 连接 synchronized
。
要改进此代码,您可以这样尝试:每 1000 个字符串表示 1000 个 http 连接,您可以创建一个 AsyncTask
到 运行 它 async
。所以您将有 100 个AsyncTask
运行并发,比你的方式快100倍
AsyncTask
的数量取决于您的设备硬件 RAM 和 CPU,您可以增加或减少它以适应您的情况。
注意:当您将 ArrayList
与 MultiThreading
一起使用时请注意,它不是 threadsafe
。
您目前的 HttpRequest
并不能提高多少。查看您的代码,您只需使用 1 AsyncTask
来执行 100,000
请求。每个请求至少需要 1s
连接,所以这将是 100,000s(太长)。有一些方法 2 可以提高你的表现:
1。生成 100,000 个线程。丑吧?不要那样做,它会破坏你的应用程序。
2。使用 100,000 个 AsyncTask
s,也不是一个好主意(正常的 execute
函数,你所有的 AsyncTask
将在单个线程上 运行,你可以使用 [=17 更改该行为=],但仍然很糟糕)。
3。将您的 HttpRequest
更改为立即发送 100,000
String
和 return
您需要的对象列表 json
。
我认为方法 3 是提高性能的最佳方法,否则,AFAIK,没有办法:)