如何“传递界面”,即CommonsWare在question below中向提问者建议的内容?>
另一个是制作DownloadFileTask 公开并传递一些东西 构造函数。在这种情况下,要尽量减少 耦合,可能是你没有 想传递一个Activity,但是有些 其他类型的界限限制 AsyncTask可以做什么。这样, 你可以选择实施 一个Activity上的接口,或者作为一个 单独的对象,或其他什么。 - CommonsWare 2010年4月27日17:44
如何让线程只访问一些(或只是一个)对象公共方法?
答案>请参阅以下答案。
真正的问题是我对界面的误解。如果将方法F的输入类型(或类的参数化)指定为接口[即F(my_interface i)]和一个对象X被传递给实现my_interface [F(X)]的那个方法,那么即使存在其他成员,也只有方法F可以访问实现my_interface的X成员。
我认为接口只在实现类上设置了约束。我不明白,当一个接口被用作一个类型时,它也会限制对实现类成员的访问。回想起来,鉴于Java是静态类型的,这是显而易见的。有关详细信息,请参阅Java tutorial。
答案 0 :(得分:0)
将接口传递给AsyncTask就像使用任何函数一样。例如:
interface MyInterface { ... }
class MyClass implements MyInterface { ... }
AsyncTask<MyInterface, Integer, Void> myAsyncTask = new ...;
myAsyncTask.execute(myClassInstance);
AsyncTask是一个Generic,它允许您指定参数类型,进度返回类型和结果类型(分别为MyInterface,Integer,Void)。您可以指定所需的任何接口,类,枚举或基元类型。
从这里开始,它只是您的标准编码。创建一个扩展接口的类,使用参数设置创建异步任务,传入类,任务只能访问接口函数。你需要小心线程问题(数据竞赛等)。
答案 1 :(得分:0)
假设您需要能够报告某些后台任务的步骤。您可以通过更改标签文本或更改通知气泡的文本来选择执行此操作。
一种方法是将标签或通知传递给后台任务:
public class BackgroundTask {
private Label labelToUpdate;
private Notification notificationToUpdate;
public BackgroundTask(Label label) {
this.labelToUpdate = label;
}
public BackgroundTask(Notification notification) {
this.notificationToUpdate = notification;
}
//...
private void reportNewStep(String step) {
if (labelToUpdate != null) {
labelToUpdate.setText(step);
}
if (notificationToUpdate != null) {
notificationToUpdate.alert(step);
}
}
}
这将BackgroundTask与UI相结合,并以两种可能的方式报告进度。如果添加第三个,则必须更改BackGroundTask的代码。
现在提取一个界面:
public interface ProgressListener {
void report(String step);
}
public class BackgroundTask {
private ProgressListener listener;
public BackgroundTask(ProgressListener listener) {
this.listener = listener;
}
//...
private void reportNewStep(String step) {
listener.report(step);
}
}
BackgroundTask现在更简单,并且不再依赖于报告进度的所有可能方式。调用者只需要为它提供ProgressListener接口的实现。对于基于标签的进度,它将执行以下操作:
BackgroundTask task = new BackgroundTask(new ProgressListener() {
@Override
public void report(String step) {
label.setText(step);
}
});
或者您的活动可以直接实施ProgressListener:
public class MyActivity implements ProgressListener {
private Notification notification;
// ...
@Override
public void report(String step) {
notification.alert(step);
}
// ...
BackgroundTask backgroundTask = new BackgroundTask(this);
}
Label和BackgroundTask之间或MyActivity和BackgroundTask之间不再有耦合。 BackgroundTask不再调用Label,Notification或MyActivity的任何方法。它只能调用它应该调用的内容:专用ProgressListener接口的方法。