Android Asynctask:内部类是否必要?

6
我尝试使用Asynctask在Android中进行网络连接,并取得了更好的结果。
我很好奇:是否有必要将Asynctask作为内部类?
我没有将它作为内部类,但是Google API指南说“必须将AsyncTask子类化才能使用。”(但我没有这样做,它仍然可以工作...) - http://developer.android.com/reference/android/os/AsyncTask.html 为什么Asynctask采用类的形式,即使它只执行一个主要功能?(我认为它应该是一个方法,而不是一个类。)

1
你是如何在不使用子类化的情况下使用它的?如果没有重写任何方法,它实际上为你做了什么?它本可以被设计成一个接口而不是一个类,但创建一个类并使一些方法可选的模式(例如onPostExecute)相当普遍。 - Jon Skeet
5
需要注意的是,文件说明要求您创建一个子类而不是内部类。您的问题是否确实涉及内部类或子类并不清楚。 - Jon Skeet
3个回答

18

'AsyncTask必须被子类化才能使用'并不意味着内部类;它意味着该类继承AsyncTask。

通常人们避免将ASyncTask用作非静态内部类,因为存在一个巨大而微妙的问题,大致如下:

  1. 您将Asynctask创建为活动的内部类,并且正在执行某些耗时操作。根据定义,内部类持有对其“外部”父级的引用(这是它们访问其父级数据的方式)。
  2. Android关闭活动并重新启动新活动(例如,当您旋转手机时)。
  3. 现在旧的活动和所有它的资源仍然被保留,因为Asynctask仍在运行并保持对旧活动的引用;因此,突然间您正在为旧版本的活动和新版本的活动使用内存。

最简单的解决方法是使用静态内部类(它无法引用其外部父项)或不同的类,并仅使用弱引用引用活动。


4

它并不一定要成为内部类,这取决于你使用它的目的。

例如,如果您有一个AsyncTask作为内部类,只有持有它的类才能使用它。但是,如果您有一个很多类都在使用的AsyncTask,您可能希望将AsyncTask作为公共类,以便每个人都可以使用它。

可以两种方式都可以工作。


3

我感兴趣的是:是否必须将Asynctask作为内部类?

不必要,您可以将其放到外部Java文件中,或者您也可以将其作为静态内部类。

AsyncTask必须被子类化才能使用。

这与类是否为内部类无关,它表示您需要创建AsyncTask的子类,即:

class MyAsyncTask extends AsyncTask 

内部类的样子如下:

class MyActivity extends Activity {
    // now MyAsyncTask  is inner to MyActivity and has full access to its instance
    class MyAsyncTask extends AsyncTask
    {}
} 

为什么Asynctask以类的形式存在,尽管它只执行一个主要函数?(我认为它应该是一个方法而不是一个类。)除了执行一个主要函数外,它的功能还包括onPostExecute和onPreExecute等。因此,将Asynctask逻辑解耦并允许重用。如果您希望Asynctask是内部类,则建议将其设为静态类-但这样为什么不将其设为外部类呢?内部类始终保留对其外部类的引用,在这种情况下,Activity将在Asynctask完成其任务(线程结束)之前不会被垃圾回收,因为网络通信需要时间,这可能导致问题-例如泄漏的引用或OOM(内存不足)异常,如果您的Activity使用大量的内存,最好将对Activity的引用保存在WeakReference中,以允许Activity被垃圾回收。

我创建了一个名为User的类,并且想在这个类中创建一些方法(例如user.login()user.getHtml()user.downloadFile()...)。但是在Android中,网络连接应该在doInBackground()方法中进行。那么,如果我想要创建所有这些方法,我应该将这些函数全部放在一个doInBackground()方法中吗? - soonoo
从doInBackground方法中调用您的User类方法。 - marcinj

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接