Как сообщить Android Studio, что переменная может стать нулевой?

У меня есть следующий код, где второй параметр «Обратный вызов» ДОЛЖЕН быть предоставлен вызывающим абонентом (причина, по которой я аннотировал его с помощью @Nonnull).

public static void load(@Nonnull final String channelId, @Nonnull final Callback callback) {
    Observable.create(new Observable.OnSubscribe<Channel>() {
        @Override public void call(Subscriber<? super Channel> subscriber) {
            try {
                Channel channel = new Channel().setApiChannel(MobileService.api().channels().get(channelId).execute(), UpdateFields.ALL);
                subscriber.onNext(channel);
            } catch (Exception e) {
                subscriber.onError(e);
            }
            subscriber.onCompleted();
        }
    }).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()). subscribe(new Subscriber<Channel>() {
        @Override public void onCompleted() {
        }
        @Override public void onError(Throwable t) {
            log.warning("could not load channelId = " + channelId + ", throwable = " + t.getMessage());
            if (callback != null) { callback.onError(channelId, t); }
        }
        @Override public void onNext(Channel channel) {
            if (callback != null) { callback.onSuccess(channel); }
        }
    });
}

Интерфейс обратного вызова выглядит следующим образом:

public interface Callback {
    void onSuccess(Channel channel);
    void onError(String channelId, Throwable throwable);
}

Чтобы перезвонить вызывающему абоненту, я делаю нулевую проверку, подобную этой

if (callback != null) { callback.onSuccess(channel); }

потому что вызывающий объект может стать нулевым в любое время, пока мой наблюдаемый выполняет свою фоновую работу. Например, вызывающим может быть представление, которое можно приостановить/уничтожить/собрать мусор [Android иногда делает забавные вещи], и в этом случае мой код не будет работать без проверки на null.

Но Android Studio не распознает такую ​​возможность и отображает предупреждение Lint, которое также не позволяет мне подавить.

Обратный вызов

Кажется, Android Studio не понимает, что переменная может стать нулевой по другим причинам, кроме моей собственной функции. Ну, я даже признаю, что этого не должно быть, поскольку она окончательная, и я был очень удивлен, когда эта строка изначально не удалась (в тот момент у меня не было проверки на нуль, потому что я считал, что она никогда не может стать нулевой).

Вопрос. Как я могу указать Android Studio подавить предупреждение, несмотря на то, что параметр помечен как @Nonnull final?

И затем: если бы кто-нибудь мог объяснить, как конечная переменная может стать нулевой в любое время, когда базовая ссылка становится нулевой. Моя концепция final заключается в том, что переменная «клонируется» и сохраняется в контексте, чего здесь явно не происходит. Является ли final «только вперед» - это означает, что мой собственный код больше не может изменять эту переменную, но вызывающая сторона все еще может?


person Oliver Hausler    schedule 17.05.2015    source источник


Ответы (1)


Я думаю, что переменная не может получить значение null, так как вы передаете ссылку обратного вызова, а не WeakReference. тем не менее, если обратный вызов выполняется в отдельном сервисном процессе, передача представления в качестве обратного вызова будет плохой практикой. в последней заметке вы можете принудительно удалить ворс с помощью @SuppressLint()

person Penman    schedule 04.02.2016
comment
Обратный вызов может стать нулевым, потому что поток пользовательского интерфейса может уничтожить его, пока я выполняю обработку в фоновом потоке. Как только эта обработка завершена, я выполняю обратный вызов в потоке пользовательского интерфейса observeOn(AndroidSchedulers.mainThread(). Я согласен с тем, что @SuppressLint() или //noinspection ConstantConditions могут подавить предупреждение. Что мне до сих пор неясно, так это то, как переменная, помеченная как final, может стать нулевой. Не следует окончательно подавлять дальнейшие переназначения (что, насколько я понимаю, включает в себя присвоение ему значения null). - person Oliver Hausler; 04.02.2016
comment
Я не уверен в этом, поэтому я спрашиваю: обрабатывает ли GC free Callbacks, как только основной поток закончит с ним, или он будет ждать, пока другие потоки также его выпустят? Последнее, что я думаю, это сделать указатель volatie, поэтому он хранится в общей памяти или что-то в этом роде!, но final на самом деле следит за тем, чтобы указатель не изменялся никаким clone или чем-то еще new instance только внутри этой области функций - person Penman; 05.02.2016