在尝试使用利用回调的第三方函数时,我试图返回指定的类型。我有一个界面
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();
}
}
然后我得到三个在接口中带有参数的声明的错误
错误:此方法不是有效的提供方法,成员注入 方法或子组件工厂方法。匕首无法实现 方法
答案 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。