前言
最近專案中要加一個體溫測量的外設模塊 利用android的串口通信 可以完美的取到測量的體溫資料
獲取到資料后,在用Handler發送資料到View渲染時 發現一個問題 就是資料能測量到 但是渲染到
TextView時有時無!
android串口通信CH340轉USB android串口通信CH340轉USB(可參考)
handleMessage
在使用Handler通信時,handleMessage()這個方法內渲染TextView資料 偶爾會丟失資料渲染
這個問題出發,尋找解決方案:
看到這樣一個關于Handler+Thread的例子
class MyThread implements Runnable{
int count = 0;
public void run() {
while(count <= 20){
try {
//每次休眠0.5秒
Thread.sleep(500);
}catch (Exception e){
e.printStackTrace();
}
//從訊息池中獲得訊息,如果沒有訊息,創建一個訊息,如果有,則取出來,由handler發送
Message message = Message.obtain();
message.arg1 = count;
message.obj = "jack";
handler.sendMessage(message);
count++;
}
}
Handler類如下:
class MyHandler extends Handler{
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
int arg1 = msg.arg1;
//接收傳過來的資料
String name = (String)msg.obj;
//渲染TextView資料
textView.append(name+arg1);
}
}
TextView渲染的結果
從圖中可以看到 count <= 20,count++ 一共執行21次回圈
得到的結果是正確的 沒有漏掉一次

如上述結果 是我想要的 所以按照這種實作流程我測驗了代碼執行
結果還是有TextView漏掉渲染的問題
將Handler設定為靜態物件
在翻閱資料的時候 看到這樣一個說明
不在執行的問題原因: onCreate()方法不是每次啟動界面都會執行的,當界面使用finish()
后界面被保存到堆疊,
第二次啟動該界面時是不會在執行onCreate()方法的,而且在這之前也沒有保存該界面物件的原型,
所以在finish()后實際上handler和loop都是空的,所以不會執行,
處理方法:1.將物件handler做為靜態物件使用,
于是 重新修改代碼 將handler設定為靜態物件
public static Handler handler;
依然是在Activity的onCreate()方法中初始化Handler后渲染TextView資料
handler = new Handler() {
public void handleMessage(Message msg) {
// 截取回傳值中的體溫資料
currentTemp1 = (String) msg.obj;
//拿到當前的體溫 資料渲染資料到頁面上顯示
setTemperatureDataRealTime(currentTemp1);
}
};
在讀體溫資料時,我的代碼是這樣處理的
每次休眠1秒防止資料發送過快
private class readThread extends Thread {
public void run() {
byte[] buffer = new byte[4096];
while (true) {
try {
//每次讀取資料 休眠1秒
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
//從訊息池中獲得訊息,如果沒有訊息,創建一個訊息,如果有,則取出來,由handler發送
Message msg = Message.obtain();
int length = MyDriverManager.driver.ReadData(buffer, 4096);
if (length > 0) {
String recv = toHexString(buffer, length);
//以16進制輸出
// String recv = new String(buffer, 0, length); //以字串形式輸出
msg.obj = recv.replace(" ", "");
handler.sendMessage(msg);
}
}
}
}
以上代碼處理資料接收以及資料發送沒有問題
但是在體溫測量這個頁面關閉的時候 會有個bug提醒
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method
'boolean android.os.Handler.sendMessage(android.os.Message)' on a null object reference
這是一個空指標例外 是handler造成的
代碼優化后是這樣的寫法 對handler和msg都做了一層!=null判斷
private class readThread extends Thread {
public void run() {
byte[] buffer = new byte[4096];
while (true) {
try {
//每次讀取資料 休眠0.1秒
Thread.sleep(100);
} catch (Exception e) {
e.printStackTrace();
}
//從訊息池中獲得訊息,如果沒有訊息,創建一個訊息,如果有,則取出來,由handler發送
Message msg = Message.obtain();
int length = MyDriverManager.driver.ReadData(buffer, 4096);
if (length > 0) {
String recv = toHexString(buffer, length); //以16進制輸出
if (msg != null) {
if (handler != null) {
msg.obj = recv.replace(" ", "");
handler.sendMessage(msg);
} else {
Log.e(TAG, "handler ------ 沒有初始化 handler = null");
}
} else {
ALog.e(TAG, "sendMessage ------ 需要發送Message為空");
}
}
}
}
}
關于記憶體泄漏
在體溫測量這個頁面 靜態使用Handler物件 可能會造成記憶體泄漏
我的處理方法是在onDestroy()方法內把handler物件置空 并且發送空資料 停止接收
@Override
protected void onDestroy() {
//結束前關閉串口
MyDriverManager.driver.CloseDevice();
super.onDestroy();
EventBus.getDefault().unregister(this);
if (handler != null) {
handler.removeCallbacksAndMessages(null);
handler = null;
ALog.e(TAG, "------ 把Handler置空 防止內容泄漏");
}
}

體溫測量
體溫測量是一個模塊 需要用到串口通信 來傳輸測量到的體溫資料 如何處理資料就要靠自己分析
一般廠家有個檔案 需要一點點摸索

總結
最近在專案中學習了android的串口通信 感覺識訓不錯
一開始在測量體溫資料時 偶爾拿不到頁面渲染 本想就這樣算了
但是本著一追到底的精神 徹底解決這個問題后心情愉悅
今天是中國民間的傳統節日七夕節 沒有物件 只能對知識追求探索
加油吧 不忘初心 方得始終

轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/294251.html
標籤:其他
