如果 AsyncTask 不是内部类...-一些问题
1)我不明白为什么Android的示例几乎使用AsyncTasks作为私有内部类。我知道将其设为内部类很方便,但是它使我们的类文件更长且难以阅读。 ShelvesActivity 的 Shelves 示例应用程序甚至有 845 行。您不认为这是一个糟糕的设计或糟糕的构造吗?
2)如果我将 ScanStorageTask 设为外部类,我必须向其传递什么?整个 Activity 或仅使用的小部件?
示例:如果我必须在 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);
1) I don't underestand why the samples of Android almost use AsyncTasks as private inner classes. I know it is convenient to make it inner class but it makes our class file longer and hard to read. ShelvesActivity of Shelves sample application have even 845 lines. Don't you think it is a bad design or bad construction?
2) If I make my ScanStorageTask external class, what do I have to pass to it? entire Activity or only used widgets?
Example: If I must use a WebView, a Button and a ProgressBar in ScanStorageTask.
I use this:
ScanStorageTask task = new ScanStorageTask(this); // "this" is activity reference, then get the webView, button, progressBar from it.
or this:
ScanStorageTask task = new ScanStorageTask(webView, button, progressBar);
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
在外部做这件事并没有什么问题,而且实际上可能是更好的设计。传递 UI 元素是一种紧密耦合,当您拥有非常大的代码库时,这种紧密耦合可能会给您带来麻烦。
为什么不在外部进行并使用 UI 控件采用的“侦听器”模式呢?让您的 ScanStorageTask 成为它自己的类,使用 onComplete 方法创建一个 OnCompleteListener 接口,并将其传递给您的 ScanStorageTask 实例(公开 setOnCompleteListener 方法或达到此效果的方法)。然后,onPostExecute 可以执行以下操作:
这样,您就可以根据数据在 Activity 内定义 UI 更新。这是更好的关注点分离,并且会减少每个类的代码行数,因为这似乎是您想要的。如果您还没有这个,请创建一个类来表示您需要传入和传出的数据,这就是您作为执行方法的参数传入任务的内容以及 onPostExecute 传递给 onComplete 的内容。
There's nothing wrong with doing it externally, and it actually might be a better design. Passing UI elements around is the kind of tight coupling that can get you into trouble when you have a really large code base anyway.
Why not do it externally and use the "listener" pattern that the UI controls employ? Make your ScanStorageTask its own class, create an OnCompleteListener interface with an onComplete method, and pass that to your ScanStorageTask instance (expose a setOnCompleteListener method or something to that effect). Then, onPostExecute can just do this:
That way, you define your UI updates inside your activity based on the data. It's better separation of concerns and will keep your lines of code per class down, as that seems to be what you'd prefer. If you don't already have this, make a class that represents the data you need to pass in and get out, and that's what you pass in to the task as a param to the execute method and what onPostExecute passes to onComplete.
内部类允许您在
onPreExecute()
、onPostExecute()
和onProgressUpdate()
内操作外部Activity
的 UI code> 而不将整个 UI 结构传递给 AsyncTask。您只需使用 activites 函数即可。这很有用,因为操作 UI 不是 AsyncTask 的主要目的。它正在执行非 UI 后台工作。为此,您通常需要传递一些参数来完成这项工作(例如提供一个 URL 来下载文件)。
当您将 AsyncTask 声明为外部时,您基本上无法访问
onPreExecute()
内的 UI 资源(根本没有参数传递给此),并且在其他两个 UI 函数内也很难访问。我想说 AsyncTask 只是为了用作内部类来完成工作和更新 UI 线程而设计的。参见说明:
(来自类文档)
Inner classes allow you to manipulate the UI of an outer
Activity
insideonPreExecute()
,onPostExecute()
andonProgressUpdate()
without passing the whole UI structure(s) to the AsyncTask. You are just able to use the activites functions for that.This is useful since manipulating the UI isn't the main purpose of an AsyncTask. It's doing non-UI background work. And for that, what you usually have to pass is some arguments to do this job (e.g. supplying a URL to download a file).
When you declare your AsyncTask external, you basically can't access your UIs resources inside
onPreExecute()
(no arguments are passed to this at all), and very hard inside the other two UI functions.I'd say AsyncTask is just made for beeing used as an inner class to do work and update the UI-thread. See the description:
(from the class documentation)
我在五月份的申请中也遇到了同样的问题。我想使用
Socket
与 PC 建立通信,并且希望我的代码可以从多个 Activity/Fragment 中重用。首先,我尝试不使用内部类,但当您必须更新 UI 时,它非常方便,所以我找到了替代解决方案:
我创建了一个外部
AsyncTask
类,负责与电脑进行通信,并在每个活动/片段中创建了内部类,仅覆盖了onPostExecute()
方法。这样我就可以重用我的代码并更新 UI。如果您只想获取任务的结果,并且响应能力对于您的应用程序来说并不重要,则可以使用 AsyncTask 类的 get() 方法。
I had the same problem in may application. I wanted to establish a communitation with a PC using a
Socket
and I wanted my code to be reusable from several Activities/Fragments.In the first place I tried not to use an inner class but it is very convenient when you have to update the UI so I found an alternative solution :
I created an outer
AsyncTask
class wich in charge to communicate with the pc and I created inner classes in each of my activites/fragments with only an override of theonPostExecute()
method. this way I can reuse my code AND update the UI.If you just want to get the result of the task and if responsiveness is not essential for your application, you can use the get() method of the
AsyncTask
class.我个人认为,如果您仅在某一点使用类,那么在那里定义它是最具可读性的 - 因此是匿名内部类。
没关系。从设计的角度来看,我只会传递实际需要的数据。但是,您需要注意一个可能的陷阱 - 当活动实例被停用(隐藏或方向更改)并且您的后台线程仍然运行并尝试显示一些更改时,您可能会收到各种错误或根本不显示任何内容。
Personally I belive that if you use class only at one point, then it's most readable to also define it there - hence the anon inner class.
It does not matter. From design perspective I'd only pass data that is actually needed. However you need to be aware on one possible pitfall - when activity instance gets deactivated (hidden or orientation changed) and your background thread still runs and tries to show some changes, then you can get various errors or nothing s shown at all.