gpt4 book ai didi

android - 为 Android 中的 URL 列表请求文件大小和 MIME 类型

转载 作者:可可西里 更新时间:2023-11-01 16:50:12 27 4
gpt4 key购买 nike

在 Android 应用程序中,我有一个像这样的图像 URL 列表:

List<String> urls = new ArrayList<String>(100);
urls.add("http://www.example.org/1.jpg");
urls.add("http://www.example.org/2.png");
urls.add("http://www.example.org/3.jpg");
urls.add("http://www.example.org/4.jpg");
urls.add("http://www.example.org/5.png");
urls.add("http://www.example.org/6.png");
urls.add("http://www.example.org/7.png");
urls.add("http://www.example.org/8.jpg");
urls.add("http://www.example.org/9.jpg");
urls.add("http://www.example.org/10.gif");
...
urls.add("http://www.example.org/100.jpg");

现在我必须获取所有这些 URL 的文件大小和 MIME 类型,当然这应该尽快完成。

我所做的是:

for (String url : urls) {
int fileSize;
try {
URLConnection urlConnection;
urlConnection = new URL(url).openConnection();
urlConnection.connect();
final String mimeType = urlConnection.getContentType();
final int fileSize = urlConnection.getContentLength();
// do something with those two pieces of information
}
catch (MalformedURLException e) {
continue;
}
catch (IOException e) {
// some special handling
}
}

但这非常慢。这是因为它使用单个线程并一个一个地请求 URL,而 Web 浏览器总是一次访问多个文件,不是吗?

那么我怎样才能让它更快呢?

对于 HttpClient,我读到过您应该重用实例,并且有一些方法可以在多线程环境中使用它们。

但是我如何使用 URLConnection 或任何其他为您提供文件大小和 MIME 类型的类来做到这一点?

编辑:

图片并不都在同一台主机上,而是分布在几台服务器上,比如 100 张图片分布在 5 个主机名上。

您能否使用几个线程或一次运行多个 AsynTasks 来完成这项工作?有没有什么需要注意的,比如回收URLConnection对象之类的?

我不太确定如何use multiple threads共享任务列表(100 个图像文件)并在之后合并结果(MIME 类型和文件大小)。你能帮忙吗?

最佳答案

把你的工作分成更小的部分,让一个 worker Thread处理它:

worker Thread :

public class Downloader extends Thread {

private final String mUrl;
private String mMimeType;
private int mFileSize;

public Downloader(String url) {
mUrl = url;
}

@Override
public void run() {
try {
URLConnection urlConnection;
urlConnection = new URL(mUrl).openConnection();
urlConnection.connect();
mMimeType = urlConnection.getContentType();
mFileSize = urlConnection.getContentLength();
} catch (IOException e) {
e.printStackTrace();
}
}

public String getMimeType() {
return mMimeType;
}

public int getFileSize() {
return mFileSize;
}
}

实例化、运行并等待worker:

ArrayList<String> urls = new ArrayList<String>(10);
// ...
ArrayList<Thread> threads = new ArrayList<Thread>(10);
for (String url : urls) {
Thread t = new Downloader(url);
threads.add(t);
t.start();
}
for (Thread t : threads) {
try {
// do not wait for other threads in main UI thread!
t.join();
//((Downloader) t).getMimeType();
//((Downloader) t).getFileSize();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

一定要注意等待 worker Thread在你的用户界面中Thread .

上面的答案应该只用于一小部分 URL。 ThreadPool可能没有必要,因为 Thread s 大部分时间会等待 IO。


这是您要求的答案 ThreadPool .

它使用相同的 Downloader类与上面的例子一样,只有一个变化:产卵 Thread s 由 ThreadPool 完成并且单个任务不需要是真实的 Thread了。所以让 Downloader实现 Runnable而不是扩展 Thread :

public class Downloader implements Runnable {

希望这就是您要找的。

public class ThreadedDownloader {

private static final int KEEP_ALIVE_TIME = 1;
private static final TimeUnit KEEP_ALIVE_TIME_UNIT = TimeUnit.SECONDS;
private static int NUMBER_OF_CORES = Runtime.getRuntime().availableProcessors();
private LinkedBlockingQueue<Runnable> mDecodeWorkQueue = new LinkedBlockingQueue<Runnable>();
private ThreadPoolExecutor mDecodeThreadPool = new ThreadPoolExecutor(NUMBER_OF_CORES,
NUMBER_OF_CORES, KEEP_ALIVE_TIME, KEEP_ALIVE_TIME_UNIT, mDecodeWorkQueue) {
@Override
protected void afterExecute(Runnable r, Throwable t) {
super.afterExecute(r, t);
Downloader d = (Downloader) r;
// do something with finished Downloader d
// like saving it's result to some sort of list
// d.getMimeType();
// d.getFileSize();

if (mDecodeWorkQueue.isEmpty()) {
onAllDownloadsFinised();
}
}
};

/** Download a list of urls and check it's mime time and file size. */
public void download(List<String> urls) {
for (String url : urls) {
mDecodeThreadPool.execute(new Downloader(url));
}
}

/** Calles when all downloads have finished. */
private void onAllDownloadsFinised() {
// do whatever you want here
// update UI or something
}
}

关于android - 为 Android 中的 URL 列表请求文件大小和 MIME 类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18755102/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com