Изменение локальной переменной из анонимного вложенного внутреннего класса - PullRequest
0 голосов
/ 20 мая 2018

Мне нужно вернуть object, который был установлен в methodB(), я много пробовал и также искал:

interface A{}
interface B{}

class Main{
  Object method(){
     Object o;

     new A(){
        methodA(){
            new B(){
                methodB(){
                    // how to use setters of o here?
                }
            }        
        }
    }

    return o;// o should contain the values set in methodB()
  }
}

Мой фактический код

  public ImageUtil saveImagetoStorage() {
    final ImageUtil imageUtil[] = new ImageUtil[1];

    filepath.putFile(mPublishedImageUri).addOnCompleteListener(new OnCompleteListener<UploadTask.TaskSnapshot>() {
        @Override
        public void onComplete(@NonNull final Task<UploadTask.TaskSnapshot> task) {

                UploadTask uploadTask = FirebaseUtil.sStorageReference.child(thumbs)
                        .child(randomName + ".jpg").putBytes(thumbData);

                uploadTask.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
                    @Override
                    public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {

                        String downloadthumbUri = taskSnapshot.getDownloadUrl().toString();
                        imageUtil[0]=new ImageUtil();
                        imageUtil[0].setImgUrl(downloadUri);
                        imageUtil[0].setImgThumb(downloadthumbUri);
                    }
                });
        }
    });
    return imageUtil[0];
}

Я что-то упустил?Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 20 мая 2018

Ваш метод должен ждать для завершения загрузки файла.

Поскольку задействованы два асинхронных вызова, один из способов сделать это - использовать CompletableFuture.

public ImageUtil saveImagetoStorage() {
    final CompletableFuture<ImageUtil> futureImageUtil = new CompletableFuture<>();

    filepath.putFile(mPublishedImageUri).addOnCompleteListener(new OnCompleteListener<UploadTask.TaskSnapshot>() {
        @Override
        public void onComplete(@NonNull final Task<UploadTask.TaskSnapshot> task) {

            UploadTask uploadTask = FirebaseUtil.sStorageReference.child(thumbs)
                    .child(randomName + ".jpg").putBytes(thumbData);

            uploadTask.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
                @Override
                public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {

                    String downloadthumbUri = taskSnapshot.getDownloadUrl().toString();
                    ImageUtil imageUtil = new ImageUtil();
                    imageUtil.setImgUrl(downloadUri);
                    imageUtil.setImgThumb(downloadthumbUri);
                    futureImageUtil.complete​(imageUtil); // Make imageUtil available
                }
            });
        }
    });
    return futureImageUtil.get(); // wait (potentially forever) until image available
}

Конечно, вы никогда не должны предполагать, что асинхронные операции могут завершиться сбоем, поэтому вам также необходимо добавить обработчики ошибок, иначе get() будет ждать вечно, поскольку complete​(...) никогда не вызывается.

0 голосов
/ 20 мая 2018

Отказ от ответственности: Этот ответ был написан до того, как «фактический код» был добавлен к вопросу.

Вы не можете, потому что o должно быть эффективно И, наконец, независимо от того, объявите вы это или нет.

Один из способов обойти это - изменить код на

Object[] o = new Object[1];

new A() {
    methodA() {
        new B() {
            methodB() {
                o[0] = ...
            }
        }
    }
}

return o[0];

Конечно, это тоже не сработает, если вы на самом деле позвоните methodB, прежде чем достигнуть оператора return o[0].

...