Search code examples
javaandroidrunnable

Access to variable within inner class which is inside a Runnable run() hock method


I have a variable called jsonString which is declared inside my button's OnClickListener event.

However, I have a long running process that gets information from a webservice that returns the jsonString.

I can't declare jsonString as final because the makeRequest function will assign a new value to it.

And I need jsonString outside as I need to pass it to another function that outside of the run method.

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();
            }
        });

Many thanks for any suggestions,


Solution

  • This is where a container object, like AtomicReference is useful.

    Consider:

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

    While an AtomicReference can be made to work consider how you will know that the jsonString has been supplied by the producer thread? Given it can take a bit of time to appear. You could spin checking for a null, or use a semaphore or wait/notify to block the new thread etc. However I would suggest that you consider using a future instead as the container class. Good futures let you register callbacks that get called when the value is supplied.

    Akka has the best implementation of Futures that I know of, see http://doc.akka.io/docs/akka/2.3.4/java/futures.html for more details.