Search code examples
androidandroid-viewrunnable

Why is my value not preserved in to the Runnable?


I have a routine which I use to set Text Views. It does some nominal processing of the names, filling in blanks, etc. Also, it runs on the UI Thread using View.Post. Here's the relevant portions of said function:

public void setValue(final String value)
{
    Log.v(TAG,"Name="+ mFieldName.getText()+" value="+value);
    //Log.v(TAG,unknown);
    mValue.post(new Runnable(){
        @Override
        public void run() {
            Log.v(TAG,"Start: Name="+ mFieldName.getText()+" value="+value);
            if (value==null)
                mValue.setText(R.string.loading);
            else
                mValue.setText(value);
            Log.v(TAG,"Posted: Name="+ mFieldName.getText()+" value="+mValue.getText());
        }   
    });

mValue and mFieldName are TextViews specified in other places. Notice the 3 Log statements. Here are 3 for the Name Accuracy:

10-27 22:27:49.491: V/OOP(19865): Name=Accuracy value=25.0 m
10-27 22:27:50.171: V/OOP(19865): Start: Name=Accuracy value=null
10-27 22:27:50.171: V/OOP(19865): Posted: Name=Accuracy value=Finding...

I'm having a very hard time understanding how the value could have changed at all during the process of creating the runnable. Any thoughts?


Solution

  • It seems like what was happening is that setValue was called multiple times without having been finished. I prevented that by checking for it, and adding a boolean viewChangePending class. I could probably have done this just as easily with a locking thread, but this seems to do the trick, so...

    public void setValue(final String value)
    {
        final String fieldName= new String((String) mFieldName.getText());
        Log.v(TAG,"Name="+ fieldName+" value="+value);
        //Log.v(TAG,unknown);
        try {
            while(viewChangePending)
                    Thread.sleep(1);
        } catch (InterruptedException e) {
            }
        viewChangePending=true;
        mValue.post(new Runnable(){
            @Override
            public void run() {
                Log.v(TAG,"Start: Name="+ fieldName+" value="+value);
                if (value==null)
                    mValue.setText(R.string.loading);
                else
                    mValue.setText(value);
                Log.v(TAG,"Posted: Name="+ fieldName+" value="+mValue.getText());
                viewChangePending=false;