Доступ к переменной внутри внутреннего класса, который находится внутри выполняемого метода блокировки run ()

#java #android #runnable

#java #Android #выполняемый

Вопрос:

У меня есть вызываемая переменная, jsonString которая объявлена внутри OnClickListener события моей кнопки.

Однако у меня есть долго выполняющийся процесс, который получает информацию от веб-сервиса, который возвращает строку JSON.

Я не могу объявить jsonString как final, потому что makeRequest функция присвоит ему новое значение.

И мне нужна jsonString снаружи, поскольку мне нужно передать ее другой функции, которая находится вне метода run.

 mBtnRegister.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {

                /* Register with web service */
                final String jsonString;

                try {
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            /* ACCESS TO VARIABLE WITHIN INNER CLASS */
                            jsonString = snapClient.makeRequest(inputStreamKeystore, 
                                keystorePassword, 
                                cnn_url, 
                                verifyEmail.createJSONRequest());
                            Log.d(TAG, "Response Code returned: "   jsonString);
                        }
                    }).start();

                } catch (IOException e) {
                    Log.wtf(TAG, e.getMessage());
                }

                verifyEmail.createJSONResponse(jsonString);
                Toast.makeText(getActivity(),
                        "Webservice Response: "   verifyEmail.getErrCode()   " "   verifyEmail.getErrDesc(),
                        Toast.LENGTH_LONG).show();
            }
        });
  

Большое спасибо за любые предложения,

Комментарии:

1. как насчет того, чтобы сделать jsonString глобальной переменной.

Ответ №1:

Вот где полезен объект контейнера, такой как AtomicReference.

Рассмотрим:

 final AtomicReference<String> jsonString = new AtomicReference();
  

Хотя атомарную ссылку можно заставить работать, подумайте, как вы узнаете, что jsonString была предоставлена потоком-производителем? Учитывая, что для его появления может потребоваться некоторое время. Вы могли бы запустить проверку на наличие null, или использовать семафор, или подождать / уведомить, чтобы заблокировать новый поток и т.д. Однако я бы посоветовал вам рассмотреть возможность использования future вместо этого в качестве класса контейнера. Хорошие фьючерсы позволяют регистрировать обратные вызовы, которые вызываются при вводе значения.

Akka имеет лучшую реализацию Futures, о которой я знаю, см. http://doc.akka.io/docs/akka/2.3.4/java/futures.html для получения дополнительной информации.

Комментарии:

1. Спасибо, будущее — это то, что меня интересует, и я проверю. Это может быть то, что я ищу.