Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/227.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在Android中的Arraylist上执行AsyncTask以更新数据库_Java_Android_Arraylist_Android Asynctask - Fatal编程技术网

Java 在Android中的Arraylist上执行AsyncTask以更新数据库

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,其中包含多达100000个字符串,并希望发出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);       
}
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
,您无法获得很大的改进。查看您的代码,您只需使用1
AsyncTask
来执行
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肯定是最好的解决方案,但不幸的是,在我的情况下,这不是一个选项。谢谢你的建议。