在Android中制作异步HTTP请求是否有可接受的最佳做法?

Jer*_*gan 42 java android http

我已经看过很多例子,他们似乎都以不同的方式解决了这个问题.基本上我只想要最简单的方法来做出不会锁定主线程并且可以取消的请求.

我们(至少)有两个HTTP库可供选择,java.net.*(例如HttpURLConnection)和org.apache.http.*也没有帮助.

关于最佳实践是什么,是否有任何共识?

小智 35

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);
   }
}
Run Code Online (Sandbox Code Playgroud)

doInBackgroundThread方法在一个单独的线程上调用(由一个线程池管理ExecutorService),并将结果传递给onPostExecute在UI线程上运行的方法.你可以叫cancel(boolean mayInterruptIfRunning)上你的AsyncTask子类来取消正在运行的任务.

至于使用java.netorg.apache.http库进行网络访问,这取决于您.我发现java.net只需尝试发布GET并读取结果,就可以使用这些库.这些org.apache.http库可以让你做任何你想要的东西HTTP,但是它们可能会更难以使用,我发现它们不能在简单的GET请求上表现得那么好(在Android上).

  • 对于阅读此答案的新用户:*注意*.对于复杂的问题,这是一个快速而肮脏的解决方案.正如Snicolas在他的回答中指出的那样,它有缺陷和错误.它在如何处理多个并发任务方面也不一致(http://developer.android.com/reference/android/os/AsyncTask.html).从Honeycomb,所有任务都将在一个线程上执行 - 这意味着你不会并行实现多个HTTP调用,除非你特别要求`THREAD_POOL_EXECUTOR`并实现所需的并发管道. (4认同)

Sni*_*las 12

实际上,AsyncTasks的设计存在一些缺陷,使其无法真正用于网络.一个简单的例子就是您将通过旋转设备来松开AsyncTask和Activity之间的链接.

看看这个帖子:你会发现AsyncTask也很容易造成内存泄漏.

AsyncTask文档清楚地表明:AsyncTask只应用于短期生活任务,而且显然,网络不属于该类别.

所以,我真的建议你看看RoboSpice.该库专为异步网络而设计,它是一种非常强大的实现方式.如果您只有几秒钟的时间来确信,请查看此inforgraphics.

RoboSpice也作为商店的演示应用程序:RoboSpice Motivations,它将解释有关Android上异步网络的所有内容.

  • 不,但欢迎比较.顺便说一句,评论开始难以阅读.如果我们同意AsyncTasks不适合网络这一事实,我们应该这样说. (2认同)