如何从线程触发PropertyChange事件?

时间:2012-04-26 20:10:58

标签: java android multithreading propertychangelistener

我正在创建一个Android应用,我希望在类maxDbRecorded的属性Measure发生更改时更新标签。所以我在Activity中实现了一个PropertyChangeListener。

public class AndroidCalibrationTestActivity extends Activity implements PropertyChangeListener {
   private Recorder recorder;
   private Thread recorderThread;
   private Measure measures;
   private TextView numberOfMaxDecibels;

   @Override
   public void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.main);
       numberOfMaxDecibels = (TextView)findViewById(R.id.txtNumberOfMaxDecibels); 

       measures = new Measure();
       measures.addPropertyChangeListener(this);

       recorderThread = new Thread((Runnable) Recorder.getInstance().runRecorder); 
       recorderThread.start();
   }

   public void propertyChange(PropertyChangeEvent event) {
        numberOfMaxDecibels.setText(event.getNewValue() + "");  
   }          
}

现在我想从我的线程中设置maxDbRecorded的值。这样textview numberOfMaxDecibels就会更新。

public class Measure {
    private double maxDbRecorded;   

    private PropertyChangeSupport pcs = new PropertyChangeSupport(this);

    public Measure() {  
    }

    //Getters and setters       
    public double getMaxDbRecorded() {  
        return maxDbRecorded;
    }
    public void setMaxDbRecorded(double maxDbRecorded) {
            double oldValue = this.maxDbRecorded;
            this.maxDbRecorded = maxDbRecorded;
            //Fires a property change event
            pcs.firePropertyChange("maxDbRecorded", oldValue, maxDbRecorded);           
    }

    //To let classes subscribe for property changed listener
    public void addPropertyChangeListener(PropertyChangeListener listener){
        pcs.addPropertyChangeListener("maxDbRecorded", listener);
    }
}

在Recorder类中,我有我设置maxDbRecorded的线程,但PropertyChanged事件不会被触发。 如果我直接从活动中设置maxDbRecorded,它确实有效。

public class Recorder {
    protected Measure m;

    private Recorder() {
        m = new Measure();
    }

    public static Recorder getInstance() {
        if(instance == null){
            instance = new Recorder();
        }
        return instance;
    }

    Runnable runRecorder = new Runnable() { 
        public void run() {
             startRecording();  
        }
    };

    public void startRecording() {
        //Here happens some recording stuff
        double maxDB;
        m.setMaxDbRecorded(maxDB);
    }     
}

我还尝试在我的Activity中创建一个Measure对象,并将此实例提供给Recorder线程。这会产生错误:$ CalledFromWrongThreadException:只有创建视图层次结构的原始线程才能触及其视图。

1 个答案:

答案 0 :(得分:1)

你应该使用android Handler类通过它发布你的ui线程。

检查:http://www.vogella.com/articles/AndroidPerformance/article.html