带有异步调用的匕首返回类型

时间:2018-12-06 22:55:00

标签: java android dagger-2

在尝试使用利用回调的第三方函数时,我试图返回指定的类型。我有一个界面

public interface AuthenticationService {
    AuthResult signInEmailPassword(String username, String password, AuthListener listener);
}

在实现接口时,我正在调用使用回调的AWS Cognito异步函数。

public class AwsCognitoAuthenticator implements AuthenticationService {
    @Override
    public AuthResult signUp(String givenName, String username, String password, final AuthListener listener) {
        userPool.signUpInBackground(username, password, userAttributes, null, signupCallback);
    --> return result from signupCallback;
    }
}

调用此方法(signUpInBackground)时仍如何返回AuthResult的类型? (我不想将其更改为void以便可以在界面上使用匕首)。

修改

我用匕首尝试了许多不同的方法,但尝试均未成功。我试图将下面的界面作为字段注入到活动中。

@Component(modules = LoginModule.class)
public interface AuthenticationService {
    void signUp(String givenName, String username, String password, AuthListener listener);
    void signInEmailPassword(String username, String password, AuthListener listener);
    void changePassword(String oldPassword, String newPassword);
    void resetPassword();
    void signOut();
}

模块

@Module
public class LoginModule {
    @Provides
    AuthenticationService provideAuthService() {
        return new AwsCognitoAuthenticator();
    }
}

然后我得到三个在接口中带有参数的声明的错误

  

错误:此方法不是有效的提供方法,成员注入   方法或子组件工厂方法。匕首无法实现   方法

1 个答案:

答案 0 :(得分:1)

您不应注释通过@Component实现的接口。 @Component的意思是,该接口定义了您希望Dagger为您实现的绑定图。

@Component(modules = LoginModule.class)
public interface AuthenticationComponent {
  AuthenticationService getAuthenticationService();
}

上面的代码告诉Dagger使用列出的@Module类和发现的带有@Inject注释的构造函数来创建在组件上列出的类。在这里,该类是AuthenticationService,根据您的LoginModule,您将获得一个具体的AwsCognitoAuthenticator。 Dagger会在AuthenticationComponent旁边生成此实现,以便您可以调用create来获取完全创建的AuthenticationService的工厂:

AuthenticationComponent authComponent = DaggerAuthenticationComponent.create();

因为您有一个绑定,而它所做的只是手动调用一个构造函数,所以您在这里不会从Dagger中获得很多好处。但是,如果您的图表随时间增长,或者您更改AwsCognitoAuthenticator来要求其他依赖项,则很容易增加其权重。


现在Dagger不参与AuthenticationService接口设计,您可以集中精力制作一个干净的API。首先,您首先需要确定AuthenticationService的行为是同步还是异步。如果要返回AuthResult,则需要创建它,因此您似乎想要同步行为。就是说,由于您接受AuthListener,因此您似乎已为异步行为做好了准备。作为您的API使用者,我不会理解这一点。请尝试以下方法之一:

  • 为您的每个方法接受AuthListener并使用它进行回调。然后,您可以返回void。大概您接受的AuthListener具有一个可以在后台任务完成并且您知道结果时接受AuthResult的方法。您的大多数方法都会返回void,因为通常没有AuthResult可以同步返回。

  • 返回ListenableFuture<AuthResult>而不是AuthResult。这意味着API的返回值是一个对象,它可以接受AuthResult准备就绪时要调用的侦听器,因此您不再需要将AuthListener作为参数。这会稍微贵一点,因为ListenableFuture需要数据结构来接受任意数量的侦听器,但是它的结构可能更好(例如,如果您需要一次侦听多个ListenableFuture实例)。

  • 双击同步API,以使您的AuthenticationService方法在完成后台任务之前不会返回。在大多数情况下,这是个坏主意,但是有可能,然后可以确保在需要返回时立即拥有AuthResult。