Java 在 Android 中发出异步 HTTP 请求是否有公认的最佳实践?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/828280/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is there an accepted best-practice on making asynchronous HTTP requests in Android?
提问by Jeremy Logan
I've seen any number of examples and they all seem to solve this problem differently. Basically I just want the simplest way to make the request that won't lock the main thread and is cancelable.
我看过很多例子,它们似乎都以不同的方式解决这个问题。基本上我只想要最简单的方法来发出不会锁定主线程并且可以取消的请求。
It also doesn't help that we have (at least) 2 HTTP libraries to choose from, java.net.* (such as HttpURLConnection) and org.apache.http.*.
我们有(至少)2 个 HTTP 库可供选择,java.net.*(例如 HttpURLConnection)和 org.apache.http.* 也无济于事。
Is there any consensus on what the best practice is?
是否就最佳实践达成共识?
采纳答案by jargonjustin
The Android 1.5 SDK introduced a new class, AsyncTaskdesigned to make running tasks on a background thread and communicating a result to the UI thread a little simpler. An example given in the Android Developers Bloggives the basic idea on how to use it:
Android 1.5 SDK 引入了一个新类AsyncTask旨在使在后台线程上运行任务并将结果传达给 UI 线程更简单一些。Android 开发者博客中给出的示例给出了如何使用它的基本思路:
public void onClick(View v) {
new DownloadImageTask().execute("http://example.com/image.png");
}
private class DownloadImageTask extends AsyncTask {
protected Bitmap doInBackground(String... urls) {
return loadImageFromNetwork(urls[0]);
}
protected void onPostExecute(Bitmap result) {
mImageView.setImageBitmap(result);
}
}
The doInBackgroundThread
method is called on a separate thread (managed by a thread pooled ExecutorService
) and the result is communicated to the onPostExecute
method which is run on the UI thread. You can call cancel(boolean mayInterruptIfRunning)
on your AsyncTask
subclass to cancel a running task.
该doInBackgroundThread
方法在单独的线程(由线程池管理ExecutorService
)上调用,结果将传递给onPostExecute
在 UI 线程上运行的方法。您可以调用cancel(boolean mayInterruptIfRunning)
您的AsyncTask
子类来取消正在运行的任务。
As for using the java.net
or org.apache.http
libraries for network access, it's up to you. I've found the java.net
libraries to be quiet pleasant to use when simply trying to issue a GET
and read the result. The org.apache.http
libraries will allow you to do almost anything you want with HTTP
, but they can be a little more difficult to use and I found them not to perform as well (on Android) for simple GET
requests.
至于使用java.net
或org.apache.http
库进行网络访问,这取决于您。我发现java.net
当只是尝试发出 aGET
并读取结果时,这些库使用起来很安静。这些org.apache.http
库可以让你做几乎任何你想做的事情HTTP
,但它们可能更难使用,我发现它们对于简单的GET
请求表现不佳(在 Android 上)。
回答by Snicolas
Actually there are a couple of flaws in the design of AsyncTasks that prevent it from being really usable for networking. An easy example is that you will loose the link between your AsyncTask and your Activity ... just by rotating your device.
实际上,AsyncTasks 的设计存在一些缺陷,使其无法真正用于网络。一个简单的例子是,您将失去 AsyncTask 和 Activity 之间的链接……只需旋转您的设备。
Have a look at this thread: you will see that AsyncTask also very easily create memory leaks.
看看这个线程:你会看到 AsyncTask 也很容易造成内存泄漏。
The AsyncTask documentation is clear about that : AsyncTask should only be used for short living tasks and, obvisouly enough, networking doesn't belong to that category.
AsyncTask 文档清楚地说明了这一点:AsyncTask 应该只用于短期任务,而且很明显,网络不属于该类别。
So, I really suggest you have a look at RoboSpice. This library has been designed for asynchronous networking and it's a very robust way to implement it. If you only have a few seconds to be convinced, look at this inforgraphics.
所以,我真的建议你看看RoboSpice。这个库是为异步网络设计的,它是一种非常健壮的实现方式。如果您只有几秒钟的时间来信服,请查看此信息图表。
RoboSpice also as a demo application on the store : RoboSpice Motivationsthat will explain everything, in depth, about asynchronous networking on Android.
RoboSpice 也作为商店中的演示应用程序:RoboSpice Motivations将深入解释有关 Android 上异步网络的所有内容。
回答by PaN1C_Showt1Me
What about an AsyncTask
with a reference to a static retained Fragment(without an UI) hosted in an Activity or another fragment ? No memory leaks, elegant async operations in a separate thread, no object reference losses.
关于什么AsyncTask
与对基准静态保持片段(无UI)中的活性或另一片段托管?没有内存泄漏,单独线程中的优雅异步操作,没有对象引用丢失。
I think this would be ok for http request, but not for file uploads / downloads. If you read carefuly, there is a sentence:
我认为这适用于 http 请求,但不适用于文件上传/下载。如果你仔细阅读,有一句话:
If you need to keep threads running for long periods of time, it is highly recommended you use the various APIs provided by the java.util.concurrent pacakge such as Executor, ThreadPoolExecutor and FutureTask.
如果您需要让线程长时间运行,强烈建议您使用 java.util.concurrent 包提供的各种 API,例如 Executor、ThreadPoolExecutor 和 FutureTask。
But they do not mention, that a servicewith a separate Thread could be a good option too. This is meant to continue executing the tasks in background, no matter what the user does. (d.g. if he uploads some file you do not want to stop this because he has left the activity)
但他们没有提到,具有单独线程的服务也可能是一个不错的选择。这是为了继续在后台执行任务,无论用户做什么。(dg 如果他上传了一些文件,您不想停止此操作,因为他已离开活动)
This linkfor samples - find the RetainedFragment.java
此示例链接- 找到 RetainedFragment.java
This linkfor AsyncTask.
AsyncTask 的此链接。
回答by Ashish Vora
You can use Async Task for Android. To make http request you can use HttpURLConnection class.
您可以使用 Android 的异步任务。要发出 http 请求,您可以使用 HttpURLConnection 类。