Textview不会显示已在模型中更新的数据(MVC)

时间:2013-03-03 22:26:40

标签: android multithreading android-activity action

我尝试了以下方法尝试从模型中更新TextView:

  1. TextChangeListeners - 错误
  2. 其他主题
  3. 的AsyncTask
  4. 添加了更新数据的刷新按钮,我强制点击
  5. 情景如下:

    1. 标准线程运行,每秒更新一次Model(MVC)对象,运行正常。
    2. 更新Model对象时,它会通知所有实现“Observer”的类。
    3. 我的GolfHomeScreen扩展了Activity并实现了Observer(下面的代码)。
    4. GolfHomeScreen.update(Observable observable,Object data)方法非常有效。它按预期每秒执行一次,并且S.O.P执行正确的数据(请参阅 - > // *#1 * )。
    5. 然后开始一个线程。我在这个网站上看到你必须要UI线程来执行更新小部件的代码,然后运行“runOnUiThread”方法 - 代码看起来像我在下面所做的那样,但我发现它有点难以理解。无论如何,这个线程运行(参见 - > // *#2 )然后执行onClick(View v)方法(参见 - > / / #3 * )。
    6. System.out.println("driverType :" + mvcModel.getDriverName());(请参阅 - > // *#4 * )完美无缺。
    7. // *#5 * - 必须更新但不会更新。
    8. 如果我实际上是单击按钮,则数据会在屏幕上正确显示。我唯一的猜测是,强制点击时屏幕不能刷新,否则我没有使用UI线程进行更新。
    9. 注意:如果下面的代码丢失了,那是因为我删除了大量代码以简化对正在发生的事情的理解。

      public class GolfHomeScreen extends Activity implements Observer
      {
          GolfHomeScreen golfHomeScreen = null;
          TextView driverName = null; // Type of driver used by golfer (eg: 1 wood)
          Button refreshData = null;
      
        @Override public void onClick(View v) //*** #3 ***
        {
          if ((v.getId()) == 12345) // ID of wood (12345 = 1 wood)
          {
                          //*** #4 ***
              System.out.println("driverType              :" + mvcModel.getDriverName()); //THIS PRINTS OUT THE LATEST DATA!!!
      
                          //*** #5 ***
                          driverName.setText(String.valueOf(mvcModel.getDriverName()));   //THIS DOESN'T AFFECT THE SCREEN?? WHY  :-(
          }
        }
      
        @Override public void onCreate(Bundle savedInstanceState)
        {
          golfHomeScreen = this;
          refreshData = indViewById(R.id.golfhomescreen_button_refreshData);
          driverName = (TextView) findViewById(R.id.golfhomescreen_text_drivername);
        }
      
        @Override public void update(Observable observable, Object data)
        {
           // #1 ***
          System.out.println("driverType              :" + mvcModel.getDriverName());
      
          golfHomeScreen.runOnUiThread(new Runnable()
          {
              @Override
              public void run()
              {
                  refreshData.performClick(); //*** #2 ***
              }
          });
        }
      

      }

1 个答案:

答案 0 :(得分:2)

我会提出一些建议和一些修正,希望你的问题不复存在。 我是这么说的,因为从概念上讲你确实有一些错误的东西,我的答案就是修复这些概念:

  • 删除GolfHomeScreen golfHomeScreen = null;golfHomeScreen = this;您不需要引用自身的对象。这只会令人困惑。这一行golfHomeScreen.runOnUiThread(new Runnable()您应该致电runOnUiThread(new Runnable()
  • System.out.pr***更改为Log.d(TAG, MESSAGE);,这只是因为这是Android专用的转储日志方式,这对您的结果无关紧要。它比标准的Java System.out更好,因为它允许您按TAG和严重性过滤这些日志。
  • 永远不要调用refreshData.performClick();或类似的东西,因为您希望执行该按钮内的操作。如果您希望从多个来源发生某件事,请创建方法doThatThing(),将操作放在那里,然后从ClickUpdate调用方法。你正在做的是一个“Rube Goldberg机器”,它正在更新某些东西,点击按钮,更改文本。只需更改文字。
  • 永远不要将视图ID与数字if ((v.getId()) == 12345)进行比较。在编译过程中系统会生成从XML创建的视图的ID,而您无法知道它是否是固定数字。您应该与该视图的静态int ID进行比较,如下所示:if(v.getId() == R.id.golfhomescreen_text_drivername)。如果视图不是用XML创建的(这里不是这种情况),您可以与实际对象进行比较if(v.equals(driverName))

通过这些更改,我相信您的代码可以正常运行。如果确实如此,请务必告诉我并将其标记为正确答案。