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);
答案 0 :(得分:14)
从外部做这件事并没有错,实际上它可能是一个更好的设计。传递UI元素是一种紧密耦合,当你拥有一个非常庞大的代码库时会让你陷入麻烦。
为什么不在外部使用并使用UI控件使用的“监听器”模式?使您的ScanStorageTask成为自己的类,使用onComplete方法创建一个OnCompleteListener接口,并将其传递给您的ScanStorageTask实例(公开一个setOnCompleteListener方法或类似的东西)。然后,onPostExecute可以这样做:
if(onCompleteListener != null)
onCompleteListener.onComplete(data);
这样,您可以根据数据在活动中定义UI更新。它可以更好地分离关注点,并且可以保持每个类的代码行数,因为这似乎是您更喜欢的。如果您还没有这个,请创建一个表示您需要传入和传出的数据的类,这就是您作为执行方法的参数传递给任务的内容以及onPostExecute传递给onComplete的内容。
答案 1 :(得分:6)
内部类允许您在Activity
,onPreExecute()
和onPostExecute()
内部操作外部onProgressUpdate()
的UI,而无需将整个UI结构传递给AsyncTask。您只能使用活动功能。
这很有用,因为操作UI不是AsyncTask的主要目的。它正在进行非UI后台工作。为此,您通常需要传递的是执行此工作的一些参数(例如,提供URL以下载文件)。
当您声明AsyncTask外部时,您基本上无法访问onPreExecute()
内的UI资源(根本没有参数传递给它),而且其他两个UI函数内部非常难。
我认为AsyncTask只是用于作为内部类来进行工作并更新UI线程。请参阅说明:
AsyncTask可以正确,轻松地使用UI线程。这个班 允许执行后台操作并在UI上发布结果 线程,而不必操纵线程和/或处理程序。
答案 2 :(得分:4)
我在may应用程序中遇到了同样的问题。我想使用Socket
与PC建立通信,我希望我的代码可以从多个活动/片段中重复使用。
首先,我尝试不使用内部类,但是当你必须更新UI时非常方便,所以我找到了另一种解决方案:
我创建了一个外部AsyncTask
类,负责与pc通信,我在每个活动/片段中创建了内部类,只重写了onPostExecute()
方法。这样我可以重用我的代码并更新UI。
如果您只想获取任务的结果,并且响应性对于您的应用程序不是必不可少的,则可以使用AsyncTask
类的get()方法。
答案 3 :(得分:2)
我个人认为如果你只在一个点上使用类,那么在那里定义它是最可读的 - 因此是anon内部类。
没关系。从设计角度来看,我只传递实际需要的数据。但是你需要注意一个可能的缺陷 - 当活动实例被取消激活(隐藏或方向改变)并且你的后台线程仍然运行并试图显示一些变化时,你可能会得到各种错误或根本没有显示任何错误。