如果AsyncTask不是内部类…… – 一些问题

1)我不会感到不安,为什么Android的样本几乎都使用AsyncTasks作为私有内部类。 我知道使它成为内部类是方便的,但它使我们的类文件更长并且难以阅读 。 ShelvesActivity of Shelves样品应用甚至有845行。 难道你不认为这是一个糟糕的设计或糟糕的建设?

2)如果我创建我的ScanStorageTask外部类,我需要传递给它什么? 整个活动或仅使用小部件?

示例:如果我必须在ScanStorageTask中使用WebView,Button和ProgressBar。 我用这个:

ScanStorageTask task = new ScanStorageTask(this); // "this" is activity reference, then get the webView, button, progressBar from it. 

或这个:

 ScanStorageTask task = new ScanStorageTask(webView, button, progressBar); 

在外部进行操作没有任何问题,实际上它可能是更好的设计。 传递UI元素是一种紧密耦合,当你拥有一个非常庞大的代码库时会让你陷入麻烦。

为什么不在外部使用并使用UI控件使用的“监听器”模式? 使您的ScanStorageTask成为自己的类,使用onComplete方法创建一个OnCompleteListener接口,并将其传递给您的ScanStorageTask实例(公开setOnCompleteListener方法或类似的东西)。 然后,onPostExecute可以这样做:

 if(onCompleteListener != null) onCompleteListener.onComplete(data); 

这样,您可以根据数据在活动中定义UI更新。 它可以更好地分离关注点,并且可以保持每个类别的代码行数,因为这似乎是您更喜欢的。 如果您还没有这个,请创建一个表示您需要传入和传出的数据的类,这就是您作为执行方法的parameter passing给任务的内容以及onPostExecute传递给onComplete的内容。

内部类允许您在onPreExecute()onPostExecute()onProgressUpdate()内操作外部Activity的UI,而不将整个UI结构传递给AsyncTask。 您只需使用活动function即可。

这很有用,因为操作UI不是AsyncTask的主要目的。 它正在进行非UI后台工作。 为此,您通常需要传递的是执行此工作的一些参数(例如,提供URL来下载文件)。

当您声明AsyncTask外部时,您基本上无法访问onPreExecute()内部的UI资源(根本没有parameter passing给它),而且其他两个UI函数内部非常难。

我说AsyncTask只是用于作为内部类来进行工作并更新UI线程。 查看说明:

AsyncTask可以正确,方便地使用UI线程。 此类允许执行后台操作并在UI线程上发布结果,而无需操纵线程和/或处理程序。

(来自课程文件 )

我在may应用程序中遇到了同样的问题。 我想使用Socket与PC建立通信,我希望我的代码可以从多个活动/片段中重复使用。

首先,我尝试不使用内部类,但是当你必须更新UI时非常方便,所以我find了另一种解决方案:
我创建了一个外部AsyncTask类,负责与pc通信,我在每个活动/片段中创建了内部类,只重写了onPostExecute()方法。 这样我可以重用我的代码并更新UI。

如果您只想获取任务的结果,并且响应性对于您的应用程序不是必需的,则可以使用AsyncTask类的get()方法。

  1. 我个人认为,如果你只在一个点上使用类,那么在那里定义它是最可读的 – 因此是anon内部类。

  2. 不要紧。 从设计角度来看,我只传递实际需要的数据。 但是,您需要了解一个可能的缺陷 – 当活动实例被取消激活(隐藏或方向更改)并且您的后台线程仍然运行并尝试显示某些更改时,您可能会收到各种错误或根本没有显示任何内容。