Java 在Android中的Arraylist上执行AsyncTask以更新数据库
我有一个字符串的ArrayList,其中包含多达100000个字符串,并希望发出HTTP请求以获取每个字符串的数据,然后创建并将其插入数据库。我现在正在用下面的代码来做这件事,但是它花费的时间太长,而且我不确定这些任务是异步执行的。有什么方法可以让这更快吗Java 在Android中的Arraylist上执行AsyncTask以更新数据库,java,android,arraylist,android-asynctask,Java,Android,Arraylist,Android Asynctask,我有一个字符串的ArrayList,其中包含多达100000个字符串,并希望发出HTTP请求以获取每个字符串的数据,然后创建并将其插入数据库。我现在正在用下面的代码来做这件事,但是它花费的时间太长,而且我不确定这些任务是异步执行的。有什么方法可以让这更快吗 ArrayList<String> objects = new ArrayList<String>(); AsyncTask<List<String>, Void, Thread> d
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);
}
ArrayList objects=new ArrayList();
AsyncTask downloadBookTask=新建AsyncTask(){
@凌驾
受保护线程doInBackground(列表…参数){
用于(字符串对象:参数[0]){
HttpURLConnection conn=null;
试一试{
conn=NetworkManager.getHttpURLConnection(新URL(对象));
连接设置连接超时(10000);
连接();
ByteArrayOutputStream bais=新的ByteArrayOutputStream();
InputStream=null;
试一试{
is=conn.getInputStream();
//一次读取4K
byte[]byteChunk=新字节[4096];
int n;
而((n=is.read(byteChunk))>0){
写(byteChunk,0,n);
}
}捕获(IOE异常){
//e、 printStackTrace();
}最后{
如果(is!=null){
is.close();
}
连接断开();
}
saveDownloadedData(对象,bais.toByteArray());
}捕获(IOE异常){
e、 printStackTrace();
} }
返回null;
}
};
downloadBookTask.executeOnExecutor(AsyncTask.THREAD\u POOL\u EXECUTOR,对象);
}
public void savedownloadedata(字符串对象,字节[]数据){
Book currentBook=新书(对象、数据);
addBookToDatabase(currentBook);
}
它会变慢,因为您的downloadBookTask
执行100000
http连接synchronized
要改进此代码,您可以尝试以下方法:每1000个字符串意味着1000个http连接,您可以创建一个AsyncTask
来运行它async
。因此,您将有100个AsyncTask
并发运行,它将比您的方法快100倍
AsyncTask
的数量取决于您的设备硬件RAM和CPU,您可以增加或减少它以适合您的情况
注意:当您将
ArrayList
与多线程
一起使用时,请小心,它不是线程安全的
,使用当前的HttpRequest
,您无法获得很大的改进。查看您的代码,您只需使用1AsyncTask
来执行100000
请求。每个请求至少需要1s
进行连接,因此需要100000秒(太长)。有一些方法可以提高你的表现:
一,。产生100000个线程。丑陋,对吧?不要这样做,它会破坏你的应用程序。
二,。使用100000个
AsyncTask
s也不是一个好主意(正常的execute
函数,所有AsyncTask
都将在一个线程上运行,您可以使用executeOnExecutor
更改该行为,但仍然很糟糕)。
三,。将您的
HttpRequest
更改为立即发送100000
String
,并返回使用json
所需的对象列表。
我认为方法3是提高性能的最佳方法,否则,恕我直言,没有办法:)如果我错了,请纠正我,但似乎您正在为字符串列表执行一个异步任务?您不想为列表中的每个字符串启动一个asynctask吗?我以前在arraylist中有一个for循环,在for循环中我为当前字符串创建了一个asynctask,但它甚至比现在慢。请使用Executor执行很长的任务,例如ExecutorService newFixedThreadPool(int-nThreads)您可以传递int 3,对于3个线程,同时执行3个任务,当一个任务完成时,将其他任务发送给执行器,在所有任务发送给执行器后,运行executor.shutdown,这将使执行器不接受新任务,但将完成当前任务的运行。感谢您的建议。我最终这样做了,现在速度快多了!更改HttpRequest肯定是最好的解决方案,但不幸的是,在我的情况下,这不是一个选项。谢谢你的建议。