当我尝试使用类似的东西
class Example {
...
private Future<String> asyncMethod() {
...
return somePromise;
}
private static void callback(Future<String> future) {
System.out.println(future.getNow());
}
public static void main(String[] args) {
asyncMethod().addListener(Example::callback);
}
}
我遇到错误
Example.java:[17,34] incompatible types: invalid method reference
incompatible types: io.netty.util.concurrent.Future<capture#1 of ? super java.lang.String>
cannot be converted to io.netty.util.concurrent.Future<java.lang.String>
使用匿名类作为侦听器没有错误
asyncMethod().addListener(new GenericFutureListener<Future<String>>() {
@Override
public void operationComplete(Future<String> future) throws Exception {
System.out.println(future.getNow());
}
});
但这很丑陋和冗长:(我该怎么做才能以最优雅的方式解决这个问题?
答案 0 :(得分:1)
您可以转换方法参考
asyncMethod().addListener((GenericFutureListener<Future<String>>) Example::callback);
它不那么冗长,但仍然不够完美。为了稍微改善此解决方案,您可以将长类型定义移至功能接口
class Example {
@FunctionalInterface
private interface Callback extends GenericFutureListener<Future<String>> {
void operationComplete(Future<String> future) throws Exception;
}
private static void callback(Future<String> future) {
System.out.println(future.getNow());
}
public static void main(String[] args) {
asyncMethod().addListener((Callback) Example::callback);
}
}
或者您可以使用键入的参数将回调包装到lambda
asyncMethod().addListener((Future<String> f) -> callback(f));
IDK,也许可以做得更好。
答案 1 :(得分:0)
您可以选择以下选项之一:
final StorageReference storRef = storageReference.child("profilePicture/"+ UUID.randomUUID().toString());
storRef.putFile(userProfileUri)
.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
@Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
storRef.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
@Override
public void onSuccess(Uri uri) {
//Log.d(TAG,"user profile url is: "+uri.toString());
saveEmailToFirebase(uri.toString());
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.d(TAG,"on download porfileuri failed"+e.getMessage());
Toast.makeText(LoginActivity.this, "profile picture uploading failed "+e.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Toast.makeText(LoginActivity.this, "profile picture uploading failed "+e.getMessage(), Toast.LENGTH_SHORT).show();
}
})
.addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() {
@Override
public void onProgress(UploadTask.TaskSnapshot taskSnapshot) {
double progress = (100.0*taskSnapshot.getBytesTransferred()/taskSnapshot
.getTotalByteCount());
Log.d(TAG,"File uploading "+(int)progress+"%");
}
});
}else {
Toast.makeText(LoginActivity.this,"Please select Profile picture",Toast.LENGTH_SHORT).show();
}
asyncMethod().addListener((GenericFutureListener<Future<String>>) future -> Application.callback(future))
从简单的private static void callback(Future<? super String> future) {
开始,您也可以通过这种方式使用回调。
注意:如果您对Future<String> future
泛型问题感到困惑,出于同样的原因,我在this SO post上加了书签。