如何在Android中创建接受参数的Runnable?

时间:2016-09-28 15:01:39

标签: java android multithreading

在iOS中,我可以将函数处理程序传递给另一个函数,这个函数处理程序可以接受一个参数,并在另一个方法中执行。 Android中怎么可能?

public class func getImage(completion: (image: UIImage?) -> ()) {
    completion(image: image)
}

Utility.getImage(completion: {image in

    imageView.image = image

})

我知道Runnableblocksclosures类似,但它不接受参数。找到here如何将参数传递给Runnable的示例,但这里的逻辑应该在一个单独的类中实现,而不是在其他方法'被调用的地方,所以代码不是可读,如iOS方式。有什么想法吗?

2 个答案:

答案 0 :(得分:2)

你不需要一个类用params创建runnable。在这里,我将分享我如何使用paran的runnable。

private Runnable createRunnable(final String params) {
    return new Runnable() {
        @Override
        public void run() {
            // your code to run in background
            // Use your param here
        }
    };
}

使用这样的方法用params创建runnable。您可以随时在runnable中使用您的参数。但它将是最终变量。所以你不能改变runnable中的变量。如果要修改变量,只需将param复制到另一个变量并修改。

答案 1 :(得分:1)

在Java中,您需要声明接口先验。您不能简单地在使用它的函数的签名中声明功能接口。因此,您的快速代码将翻译为:

// In java 7
// Declare your interface
public interface ImageListener {
    public void completed(Image image);
}

// ...
// Define your `getImage` function to use the listener
public static void getImage(ImageListener completion) {
    completion.completed(image);
}

// ...
// Call the function
Utility.getImage(new ImageListener() {
    public void completed(Image image){
        imageView.image = image;
    }
});

或者使用Java 8,只需:

// Skip the interface declaration and use a predefined Java 8 Functional interface:
public static void getImage(Consumer<Image> completion) {
    completion.accept(image);
}

// ...
// Call the function
Utility.getImage(image -> imageView.image = image);

有几点回应Janos的评论:

  • 定义接口允许您使用多种方法,例如在发生错误时调用的方法。使用闭包只需要在接口中使用尽可能多的块,只需要一个接口,就需要一个接口。
  • 接口可以是匿名的,如我给出的示例,但它也可以由对象实现,允许轻松地重用块等。
  • 在Java 8中,大多数功能接口已经定义,因此您无需自己定义它们。
  • 创建命名接口赋予其特定的含义和目的。当您将其作为参数接收时,很清楚您应该如何处理它。
  • 有一些界面方法的命名约定可以帮助您理解上下文。例如,在Android中,当接口方法以on开头时,应该在主线程上调用它。它有助于API的开发人员表达意图,并帮助API的用户了解期望的内容。自我记录,如果你愿意的话。

所以,不是噩梦,在许多情况下,如果你真的不想这样做,你甚至不必实施它。)