2012-01-10 87 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