【问题标题】:Android/Java : Watch for variable change from main classAndroid/Java:观察主类的变量变化
【发布时间】:2013-06-12 12:06:02
【问题描述】:

我不想检查我的 xClass 中的变量是否从我的主类更改。问题是,我的变量仅在单击 ImageView 并且在线程中运行时才会更改,所以我不想检查在我的主类中的一个while循环(我不知道这是否可能)中,当变量改变时做某事。所以这是我尝试过的,但是当我运行程序时它只是停止,什么也不做。

Thread setBack = new Thread() {
            public void run() {
                knight.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Counter++;
                        //also have some code here.
                    }
                }
};

所以这是我的线程,计数器是我想观察的值。我使用 get 方法返回值。

public boolean getCounter(){
            if(Counter>=1){
                return true;
            }
            return false;
}

所以这表明值发生了变化(计数器是全局变量)。 这就是我在主课上所做的。

while (true) {
    if (xClass.getCounter()) {
        // do something
    }
}

这是我的程序实际停止运行的地方。我想不出任何其他方法来获取值已更改的指示符。

感谢您的帮助,谢谢。

【问题讨论】:

  • 除了提到的所有其他内容之外,请确保变量被声明为 volatile。您的整体方法听起来有问题 - 一旦满足条件,让后台线程在 ui 线程上运行某些东西可能会更好,这样您就可以避免阻塞 ui 线程。

标签: java android class


【解决方案1】:

对于observer pattern,这听起来是个不错的选择。您在这里要做的不是通过Counter++ 而是使用诸如

之类的函数来更改变量
private void incrementCounter() {
  Counter++;
  observer.notify();
}

还将以下内容添加到您的xClass.java

private VariableChangeObserver observer;

public void register(VariableChangeObserver observer) {
  this.observer = observer;
}

那么你可以让Main.java实现如下接口:

public interface VariableChangeObserver {
  /**
   * Called whenever the variable is changed.
   */
  public void notify();
}

最后但同样重要的是,将 notify() 函数添加到您的 Main.java 中,当值更新时,它会执行您想做的任何事情。

其他信息: 一般来说,您将拥有一个观察者列表,而不仅仅是一个。但是,如果您知道在任何给定时间您只会有一个观察者,这就足够了。

【讨论】:

    【解决方案2】:

    因为您的while(true) 在主线程中运行,它会阻塞应用程序。

    将其放入Thread 并启动它。这样它就不会阻止应用程序,而是会做你想做的事。

    new Thread() {
        @Override
        public void run() {
            while (true) {
                if (xClass.getCounter()) {
                    //your code
                }
            }
        }
    }.start();
    

    【讨论】:

    • 实际上我已经尝试过了,但是我得到了我需要使用 looper.prepare 的异常。这让事情变得更加复杂。我想要的一个最佳解决方案是,我只有一个 bool 变量,当我单击图像时会发生变化,并以某种方式通知已更改的主类。
    • 那么你需要一个观察者模式。当变量更改时触发属性更改事件,并在需要时注册属性更改侦听器。
    【解决方案3】:

    不是最漂亮的解决方案,但您可以在 xClass 中使用静态布尔标志。由于你知道变量的值只有在点击 imageview 后才会改变,所以你可以在变量修改后立即设置 flag=true。

    knight.setOnClickListener(new View.OnClickListener() {
    
        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            Counter++;
            mainClassObject.callBackFunction();
            //also have some code here.
        }
    }
    

    在 Main 类中,您将需要定义处理变量更改的回调函数。

    public static callback(int newValue){
        //handle here
    }
    

    几乎不应该将无限的 while 循环用作实际问题的解决方案。更喜欢事件驱动模型。

    【讨论】:

      【解决方案4】:

      我不完全理解你的代码的意图,所以我会尽力回答。

      1) 我建议您重新了解命名约定。以大写开头的对象名称通常保留给类名称,例如视图、活动、自定义类等。 由于我假设您的计数器是一个变量,因此我将其称为“计数器”而不是“计数器”。

      2) 如果您打算这样做,那么在主“线程”中使用循环实际上是可以的(我假设您的意思是线程,而不是类),但要​​小心它会阻塞主线程除了执行特定循环之外,线程不会做任何其他事情。

      3) 别忘了,你必须在线程上调用 start() 函数才能真正让它运行代码。

      4) 在后台线程中处理 UI 元素时,请确保在 runOnUiThread() 中调用对 UI 的任何更改。参考how to use runOnUiThread

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-04-24
        • 1970-01-01
        • 2019-02-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多