【问题标题】:Execute AsyncTask on Arraylist in Android to Update database在 Android 中对 Arraylist 执行 AsyncTask 以更新数据库
【发布时间】:2015-03-28 03:14:18
【问题描述】:

我有一个包含多达 100,000 个字符串的字符串数组列表,并希望发出 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);       
}

【问题讨论】:

  • 如果我错了,请纠正我,但您似乎正在为字符串列表执行一个异步任务?您不想为列表中的每个字符串启动一个异步任务吗?
  • 我曾经有一个 for 循环遍历 arraylist,在 for 循环中我为当前字符串创建了一个 asynctask,但它比现在慢
  • 使用 Executors 处理很长的任务,例如 ExecutorService newFixedThreadPool (int nThreads) 你可以传递 int 3,用于 3 个线程并同时执行 3 个任务,当一个任务完成时发送另一个任务给执行者,在你所有的任务都发送给执行者之后,运行executor.shutdown,这将使执行者不接受新任务,但会完成当前的任务。

标签: java android arraylist android-asynctask


【解决方案1】:

因为你的downloadBookTask 执行100,000 http 连接synchronized,所以它很慢。

要改进此代码,您可以尝试这样:每个 1000 个字符串意味着 1000 个 http 连接,您可以创建一个 AsyncTask 来运行它 async。所以您将有 100 个 AsyncTask 运行并发,它将是 100比你的方式快几倍。

AsyncTask 的数量取决于您的设备硬件 RAM 和 CPU,您可以根据自己的情况增加或减少它。

注意:ArrayListMultiThreading 一起使用时要小心,它不是threadsafe

【讨论】:

  • 感谢您的建议。我最终这样做了,现在它更快了!
【解决方案2】:

您当前的HttpRequest 无法提高很多。查看您的代码,您只需使用 1 AsyncTask 来执行 100,000 请求。每个请求至少需要1s 进行连接,所以它将是100,000s(太长)。有一些方法2可以提高你的表现:
1。产生 100,000 个线程。丑对不对?不要那样做,它会破坏你的应用程序。
2。使用 100,000 个AsyncTasks,也不是一个好主意(正常的execute 函数,你所有的AsyncTask 将在一个线程上运行,你可以用executeOnExecutor 改变这种行为,但仍然很糟糕)。
3。将您的HttpRequest 更改为一次发送100,000 Stringreturn 您需要的对象列表json
我认为方法 3 是提高性能的最佳方法,否则,AFAIK,没有办法 :)

【讨论】:

  • 更改 HttpRequest 肯定是最好的解决方案,但不幸的是,在我的情况下,这不是一个选择。谢谢你的建议。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-04
  • 2013-12-27
  • 2014-05-14
  • 1970-01-01
相关资源
最近更新 更多