黃慧 李荊軒
(1.中國第一汽車股份有限公司研發總院,長春130013;2.一汽大眾汽車有限公司,長春130011)
車載娛樂系統中的操作系統主要包括WinCE、QNX、Linux、Android、鴻蒙OS和阿里OS。由于汽車制造企業在定制方面的需求日益增多,Android系統因其生態化、靈活性和受用戶歡迎的優點,在市場上占據越來越大的份額。隨著搭載Android系統的車載娛樂系統增多,對Android應用程序訪問整車電子控制器件的需求也越來越多。車載娛樂系統的Android應用程序需要能夠正確地發送控制指令給整車電子器件,并將其狀態反饋到界面上,因此需要研究一種高效的設計模式來實現這一目標。因此,本文對車載娛樂系統中Android應用程序的設計模式進行了研究。
車載娛樂系統中使用Android應用程序訪問CAN網絡與Android 終端應用程序訪問HTTP 網絡有所不同。車載應用程序的主要功能特點在于管理涉及控制器局域網絡的業務邏輯和用戶界面。與Android終端應用程序相比,車載應用程序發送和接收CAN網絡報文具有以下不同之處:
(1)請求CAN網絡得到反饋所需的時間比請求HTTP網絡更長,這是因為請求CAN網絡需要考慮對方電子控制單元(Electronic Control Unit,ECU)計算的時間。
(2)CAN網絡會定時反饋對方ECU的狀態。
(3)如果對方ECU 存在非預期錯誤,將會通過CAN網絡反饋無效值或保留值。
本文研究了適用于車載應用的CAN 網絡應用程序設計模式和方法,并探討了適用于車載應用的HTTP網絡應用程序設計模式和方法。本文以Java作為Android 系統的上層開發語言,并使用Java 代碼作為示例。
模型-視圖-控制器(Model-View-Controller,MVC)是一種常用的設計模式,用于組織和管理軟件應用程序中的交互和數據流。MVC設計模式,如圖1所示[4]。

圖1 MVC設計模式邏輯[4]
Model代表數據模型,負責保存和管理數據。當數據發生變化時,Model負責通知View更新界面顯示。
View代表用戶界面,接收用戶的請求并將其傳遞給Controller。View 主要負責與用戶進行交互和展示數據。
Controller是控制器,負責處理業務邏輯。當Controller對業務進行處理后,會通知Model進行數據更新。
(1)模塊職責劃分明確。主要劃分為Model、View和Controller模塊,有利于代碼維護。
(2)這種設計模式使得數據、界面和業務邏輯之間的耦合度降低,提高了代碼的可維護性和可擴展性。
(1)在Android 開發中,通常將Activity 組件作為控制器(Controller)角色來執行。然而,在實際業務應用中,Activity也會控制一些涉及業務邏輯刷新的用戶界面(User Interface,UI)元素,例如進度條等。這就導致部分View 和Controller 的功能合并在同一個類別中,使得Activity 的代碼逐漸膨脹。這種情況下,View和Controller 之間存在耦合,不符合模型設計的初衷,給維護帶來了困難。
(2)此外,View 和Model 之間也存在一定的交互邏輯,并沒有完全分離開來,導致View 和Model 之間也存在耦合。
(3)上述設計還僅僅實現了在車載應用中給對方ECU發送指令,并默認對方ECU能成功執行并刷新界面。但實際上,對方ECU并不一定能成功執行該指令,并且從CAN網絡接收到反饋的時間也相對較長。因此,在Controller中需要額外設計,以便在對方ECU執行失敗或用戶頻繁發送指令導致對方ECU不斷返回反饋的情況下,能正確通知Model并相應地更新View。這使原本已經龐大的Controller復雜度和大小進一步增加。
(1)MVC 不適合用于處理與CAN 網絡相關的業務和UI邏輯。
(2)MVC可以應用于簡單的數據界面控制邏輯。
(1)Model層
通過抽象出符合業務邏輯的Model 層,可以實現數據的保存和處理,并在處理完成后通知UI層更新顯示內容。

(2)View層
在Android應用中,View層作為用戶界面,通常指的是Activity 的xml 布局文件。這些布局文件定義了用戶界面的組件和布局結構,包括各種UI 元素,如按鈕、文本框和圖像等。通過使用這些xml布局文件,可以創建出具有交互性和可視化效果的用戶界面。View實現程序如下:

(3)Controller層
Controller 層即創建Activity,Controller 層起到了連接View層和Model層的作用,負責協調界面與數據之間的交互。通過處理View層傳遞過來的事件,Controller 層可以響應用戶的操作,并將必要的數據處理任務交給Model層來完成。這樣可以實現界面和數據的分離,同時提高代碼的可維護性和復用性。
Controller實現程序如下:

模型-視圖-表示器(Model-View-Presenter,MVP)設計模式邏輯如圖2所示。

圖2 MVP設計模式邏輯[9]
Model 作為模型層,負責數據的加載、存儲和處理,其角色和作用與MVC中的Model層是相同的。
View作為視圖層,負責展示界面的數據并與用戶進行交互。它接收用戶的請求,并將請求傳遞給Presenter進行處理。View的角色和作用與MVC中的View層是相對應的。
Presenter負責邏輯業務的處理,接收來自View的用戶請求,并在需要的情況下修改Model,然后通知View進行界面的更新顯示。與MVC中的Controller相比,Presenter 的角色和職責有所區別。在MVP 架構中,Presenter 負責處理業務邏輯,并起到連接View 和Model的橋梁作用。
(1)View和Model的分離
在MVP 架構中,View 負責處理用戶界面的展示和用戶輸入的響應,而Model 負責處理數據的獲取和處理。二者之間的分離使得修改視圖不會對模型造成影響,也使得View 可以進行組件化,提高了代碼的可維護性和可重用性。
(2)Presenter的復用和任務細分
Presenter 負責處理業務邏輯和交互邏輯,所有的交互都發生在Presenter 中。通過將復雜的任務分解成細小的任務,提高代碼的可讀性和可維護性。而且一個Presenter可以被多個View共享,實現了Presenter的復用,減少了代碼的冗余。
(3)接口化的交互
Presenter通過接口和View進行交互,通過定義接口來規范交互方式,有利于測試和維護。通過接口的使用,可以實現模塊之間的解耦,方便進行單元測試和模塊替換。
(4)通用Presenter和HTTP請求
由于Model 和Presenter 的設計模式,可以定義多種通用的Presenter,用于處理不同的業務邏輯和請求。比如可以定義通用的Presenter用于處理HTTP網絡請求,并通過即時的HTTP反饋進行界面設置,提高用戶體驗。這也是MVP架構的靈活性之一。
(1)接口維護成本增加
在頁面邏輯復雜的情況下,隨著功能的增加,對應的Presenter 和View 的接口也會增多。這可能增加了代碼的復雜性和維護成本。可以考慮根據實際情況對接口進行合理的設計和劃分,避免接口過于龐大和冗余。
(2)狀態保存與恢復
在Android 中,一般使 用OnSaveInstanceState 和OnRestoreInstanceState 來保存和恢復Activity 的狀態。然而,在MVP設計模式中,View不應該直接操作Model,這可能導致狀態的保存和恢復變得不合理,并增加了Model 和View 之間的耦合性。可以考慮使用其他方式來實現狀態的保存和恢復,如使用View Model層來管理狀態。
(3)UI更改導致Presenter接口變更
當UI發生更改時,可能需要對Presenter中的一些接口進行修改,存在一定的耦合。這是因為Presenter負責處理業務邏輯和更新UI。可以考慮使用抽象和接口來降低耦合性,并且盡量將UI變更的影響范圍控制在最小范圍內。
(1)MVP 不適合應用于處理CAN 網絡相關的業務及UI邏輯。
(2)MVP 適合應用于處理HTTP 網絡相關的業務及UI邏輯。
(1)Model層
Model層負責處理數據的獲取、存儲和處理,可以包含數據庫操作、網絡請求、文件讀寫等邏輯,并且Model只與Presenter發生交互。
Model實現程序如下:

(2)View層
View 層xml 布局 文件和MVC 中View 層的xml 布局文件是相同的。View實現程序如下:

Activity 達到接收到View 的事件,通過實現View的接口[13],通過持有Presenter 的引用,將View 和Presenter進行聯系。
View實現程序如下:

(3)Presenter層
Presenter負責處理業務邏輯,通過IPresenter接口實現View 調用,它可以定義一系列的方法,用于接收View 層的事件和數據請求,并根據業務邏輯進行處理,以實現兩者之間的交互。
Presenter實現程序如下:

模型-視圖-視圖模型(Model-View-View Model,MVVM)如圖3所示[3,14]。

圖3 MVVM設計模式邏輯[3]
MVVM 模式可以理解為對MVC 模式的改進和優化。在MVVM模式中,Model負責處理數據的加載和存儲,與MVC模式中的Model層設計策略相同。當Model數據更新后,它會將新數據傳遞給View Model。
View是視圖層,負責展示界面數據并與用戶進行交互,與View Model之間存在雙向交互關系。View層通過綁定View Model 來實現,當ViewModel 的數據改變時,View會自動更新相應的UI,反之亦然。
View Model 是視圖模型,負責完成View 與Model的交互,處理業務邏輯,并通知Model進行更新操作。
(1)View Model 和View 的耦合度相比MVP 模式更低。View Model 負責處理和提供數據,UI的變化無需特殊處理,只需通過數據綁定實現。這樣做,只需關注數據處理,UI處理也就自然完成了。
(2)View Model 中只包含數據和業務邏輯,方便進行單元測試。
(3)由于車機CAN網絡的消息經常發生并且不需要向對應的ECU發送請求,同時也會有來自對應ECU的反饋消息。因此,MVVM 模式適合用于IVI 車機端對CAN網絡的請求,實現通過數據驅動UI的修改。
盡管使用Data Binding 機制時,View 層的Data Binding 需要按規范實現,否則可能導致View 布局問題以及與Activity 中代碼相關的問題,并且可能不利于調試,需要一定的開發經驗。但是,由于MVVM 模式能很好地適用于處理與CAN 網絡相關的復雜業務和UI邏輯,因此,在基于Android系統的車機應用中訪問CAN網絡時,MVVM是一種較為理想的設計模式。
(1)Model層
Model層在MVC、MVP和MVVM 設計模式中都是負責數據的加載和處理。在這些設計模式中,Model層的職責是從數據源獲取數據,并進行數據的處理和邏輯操作。
Model實現程序如下:

(2)View層
此布局與其它設計模式中的view層的不同之處在于,增加了Data Binding。在使用Data Binding 的情況下,布局文件中的視圖和數據源可以直接進行綁定,使得數據更新和顯示更加自動化和簡潔。通過在布局文件中使用特定的語法和屬性,可以將數據源與對應的視圖進行關聯,當數據源發生變化時,視圖會自動更新。
View實現程序如下:

MVVM Activity 作用為將View和View Model 進行綁定。
MVVM實現程序如下:

(3)View Model層
View Model 屬于連接視圖層和模型層的中間件,能夠觀察到綁定的數據的變化,并對視圖內容做對應的更新,能夠監聽視圖的變化,且通知數據發生改變。
View Model實現程序如下:

在此項研究中,對MVC、MVP、MVVM 這3種車載Android 應用設計模式進行了邏輯分析,并對其優缺點進行了比較。最后,總結了在車載終端應用中的實現步驟和結果。然而,結合實際業務的實現中,還需要進行更多的設計工作來進行優化和細化。
Android 車載應用提供了強大的開發工具,能夠優化用戶交互,并推動了車輛智能化發展。隨著技術逐漸進步,更多交互、更好體驗的Android應用將會在車載終端應用。