2012-01-10 88 views
1

我的应用程序每秒从蓝牙设备接收数据4次,解析并将其显示在屏幕上。一切正常,直到屏幕方向改变,然后textViews恢复到我的onCreate中设置的默认值,并不会从那里改变。屏幕旋转导致TextViews停止更新

我仍然从蓝牙线程接收来自我的消息处理程序的数据,并且解析工作正常,但是我的updateUI()方法什么都不做。所有在updateUI()中的是将TextView的文本设置为值,如tv_text.setText(doubleValue);.再次,这个工作正常之前,屏幕旋转或睡觉。

当屏幕旋转时View ID是否改变,所以我的TextView是错误的?我如何解决这个问题?我已经看到其他TextView问题的人失去了它的数据,但我不确定这是否是同样的问题,因为我无法在旋转后再次设置文本。

谢谢。

编辑:我发现了一些奇怪的行为。

  1. 如果我在连接到BT设备之前旋转屏幕,它将在我连接时起作用。但是当我再次旋转时它会停止。

  2. 当我旋转时,文本视图显示在连接之前最后分配给它的值。例如,如果执行tv.setText(“10”),它将显示10.然后我连接,并使用正确的值更新。然后我旋转,它回到显示10 ...

  3. 我唯一一次在我的updateUI()代码中设置文本值,并且在收到并解析消息后调用它。

现在我真的很困惑......

EDIT 2

OK,我做了一些更多的测试ANS我想我可能已经找到了原因。当我试图断开蓝牙连接时,我发现它并未断开连接。所以然后我在旋转之前尝试断开连接,然后再次连接并工作。

所以我相信,当onCreate再次运行时,它会重复我的蓝牙通信线程并忽略旧的线程。问题是我不知道如何初始化BTComm对象,以便在活动被销毁并重新创建时它仍然可以工作,它仍然可以工作并且可以与UI进行通信。下面是一些代码:

@Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     if (btc == null){ 
      btc = new BTComm(this, messageHandler); 
     } 

     tv_temp1 = (TextView) findViewById(R.id.tv_temp1); 
     tv_temp2 = (TextView) findViewById(R.id.tv_temp2); 
     tv_temp1Label = (TextView) findViewById(R.id.tv_temp1Label); 
     tv_temp2Label = (TextView) findViewById(R.id.tv_temp2Label); 
     tv_status = (TextView) findViewById(R.id.tv_status); 
    } 

和处理来自BT通讯类接收(BTC)

Handler messageHandler = new Handler() { 
     public void handleMessage(Message msg) { 
       switch(msg.what){ 
       case BTComm.MESSAGE_CONNECTED: 
        Toast.makeText(LambdaActivity.this, "Connected!", Toast.LENGTH_SHORT).show(); 
        tv_status.setText("Connected."); 
        mode = MODE_CONNECTED; 
        break; 
       case BTComm.MESSAGE_READ: 
        parse(msg.getData().getString("results"), msg.getData().getLong("time")); 
        break; 
       case BTComm.MESSAGE_DISCONNECTED: 
        Toast.makeText(LambdaActivity.this, "Disconnected!", Toast.LENGTH_SHORT).show(); 
        tv_status.setText("Not connected..."); 
        mode = MODE_NOT_CONNECTED; 
        break; 
       } 
     } 

    }; 

如果我断开,每次屏幕被重新连接它的工作邮件处理程序旋转,但这会中断应用程序的数据记录功能的功能,所以我不想这样做...如果我锁定方向到风景,屏幕显然不会旋转并导致此问题,但如果手机睡觉时,当它以更多的肖像醒来时,它会旋转到风景模式,问题就会发生。

回答

2

为了防止其他人遇到此问题,我找到了一个修复程序。

我最终将蓝牙监听器移动到了服务中,当它从BT设备接收到数据后,它就会广播它并被我的UI活动接收。

一些更多的信息可以在我的其他问题可以发现,这里:Android background task and lifecycle

+0

为了解决我的TextView(在ScrollView中)没有使用快速流式文本更新的问题,我尝试了其他所有在SO上讨论过的其他方法:(post)invalidate,requestLayout,runoOnGuiThread等。只有BroadcastReceiver工作。我也没有需要一个服务,只是一个简单的意图b'cast从线程告诉活动更新TextView。 – PVS 2013-05-24 15:36:01

0

你在哪里设置你的textView的参考机会是你的textview的引用已经丢失。

,你也可以尝试

((TextView)findViewById(yourtextviewid)).setText(doubeValue) 

这样,你是不是静态地抱着参考。

没有看到您的代码;特别是你的活动生命周期的功能,这是在黑暗中刺。

编辑: 您可以尝试使处理程序和蓝牙对象都是静态的,这样它们就可以在类的实例之间共享......但是,我建议您查看蓝牙连接的服务实现。

+0

我认为这可能是它。我在onCreate()中设置参考。有没有一个地方可以在屏幕旋转或关闭后重新设置它们?我会尝试你的代码,看看它是否也能工作。 – Matt 2012-01-10 02:02:06

+0

该代码似乎不起作用,我更新了我原来的问题。 – Matt 2012-01-10 02:20:02

+0

你确定textview是你的问题,而不是你的蓝牙接收器..特别是与您的问题更新。 – snowCrabs 2012-01-10 02:51:41

1

我不确定它是如何影响蓝牙通信的,但是如果您将android:configChanges="orientation|keyboardHidden"放入您的AndroidManifest.xml文件中用于您希望收到更改通知的活动,则可以处理onRetainNonConfigurationInstance()中的那些配置更改。在你的活动被销毁和重建之前,这个方法会被调用。

应该注意的是,如果您的目标是Honeycomb或更高版本,并且您应该使用Fragment.setRetainInstance(boolean),则不建议使用此方法。

+1

只是一个说明,谷歌没有正式认可这种方法,我认为Reto Meier在谷歌I/O上称它为“懒惰” – SeanPONeil 2012-01-10 02:31:18

+0

@ oneilse14:当我第一次学习如何做到这一点时,我基本上从开发人员文档[这里](http://developer.android.com/guide/topics/resources/runtime-changes.html#RetainingAnObject)。似乎至少在未来他们不会改变它。 – Robert 2012-01-10 02:37:03