相信很多剛接觸AndroidTV開發的開發者,都會被各種焦點問題給折磨的不行。不管是學技術還是學習其他知識,都要學習和理解其中原理,碰到問題我們才能得心應手。下面就來探一探Android的焦點分發的過程。
Android焦點事件的分發是從ViewRootImpl的processKeyEvent開始的,源碼如下:
源碼比較長,下面我就慢慢來講解一下具體的每一個細節。
dispatchKeyEvent方法返回true代表焦點事件被消費了。
ViewGroup的dispatchKeyEvent()方法的源碼如下:
(2)ViewGroup的dispatchKeyEvent執行流程
(3)下面再來瞧瞧view的dispatchKeyEvent方法的具體的執行過程
驚奇的發現執行了onKeyListener中的onKey方法,如果onKey方法返回true,那麼dispatchKeyEvent方法也會返回true
可以得出結論:如果想要修改ViewGroup焦點事件的分發,可以這么干:
注意:實際開發中,理論上所有焦點問題都可以通過給dispatchKeyEvent方法增加監聽來來攔截來控制。
(1)dispatchKeyEvent方法返回false後,先得到按鍵的方向direction值,這個值是一個int類型參數。這個direction值是後面來進行焦點查找的。
(2)接著會調用DecorView的findFocus()方法一層一層往下查找已經獲取焦點的子View。
ViewGroup的findFocus方法如下:
View的findFocus方法
說明:判斷view是否獲取焦點的isFocused()方法, (mPrivateFlags & PFLAG_FOCUSED) != 0 和view 的isFocused()方法是一致的。
其中isFocused()方法的作用是判斷view是否已經獲取焦點,如果viewGroup已經獲取到了焦點,那麼返回本身即可,否則通過mFocused的findFocus()方法來找焦點。mFocused其實就是ViewGroup中獲取焦點的子view,如果mView不是ViewGourp的話,findFocus其實就是判斷本身是否已經獲取焦點,如果已經獲取焦點了,返回本身。
(3)回到processKeyEvent方法中,如果findFocus方法返回的mFocused不為空,說明找到了當前獲取焦點的view(mFocused),接著focusSearch會把direction(遙控器按鍵按下的方向)作為參數,找到特定方向下一個將要獲取焦點的view,最後如果該view不為空,那麼就讓該view獲取焦點。
(4)focusSearch方法的具體實現。
focusSearch方法的源碼如下:
可以看出focusSearch其實是一層一層地網上調用父View的focusSearch方法,直到當前view是根布局(isRootNamespace()方法),通過注釋可以知道focusSearch最終會調用DecorView的focusSearch方法。而DecorView的focusSearch方法找到的焦點view是通過FocusFinder來找到的。
(5)FocusFinder是什麼?
它其實是一個實現 根據給定的按鍵方向,通過當前的獲取焦點的View,查找下一個獲取焦點的view這樣演算法的類。焦點沒有被攔截的情況下,Android框架焦點的查找最終都是通過FocusFinder類來實現的。
(6)FocusFinder是如何通過findNextFocus方法尋找焦點的。
下面就來看看FocusFinder類是如何通過findNextFocus來找焦點的。一層一層往下看,後面會執行findNextUserSpecifiedFocus()方法,這個方法會執行focused(即當前獲取焦點的View)的findUserSetNextFocus方法,如果該方法返回的View不為空,且isFocusable = true && isInTouchMode() = true的話,FocusFinder找到的焦點就是findNextUserSpecifiedFocus()返回的View。
(7)findNextFocus會優先根據XML里設置的下一個將獲取焦點的View ID值來尋找將要獲取焦點的View。
看看View的findUserSetNextFocus方法內部都幹了些什麼,OMG不就是通過我們xml布局裡設置的nextFocusLeft,nextFocusRight的viewId來找焦點嗎,如果按下Left鍵,那麼便會通過nextFocusLeft值里的View Id值去找下一個獲取焦點的View。
可以得出以下結論:
1. 如果一個View在XML布局中設置了focusable = true && isInTouchMode = true,那麼這個View會優先獲取焦點。
2. 通過設置nextFocusLeft,nextFocusRight,nextFocusUp,nextFocusDown值可以控制View的下一個焦點。
Android焦點的原理實現就這些。總結一下:
為了方便同志們學習,我這做了張導圖,方便大家理解~
㈡ Android TV(一)(入門准備)
以下內容是對Google Android TV文檔的翻譯,可能存在錯誤,請讀者以官方文檔為准
官方地址
在文檔中Google對Android TV的提出了許多要求,如果你只是使用它的一些UI元素,你可以不用太注意這些要求。
官方地址 鏡像地址
TV應用在手機和平板電腦上使用相同的項目結構。這意味著你可以修改已經存在的應用使其在電視設備上運行或者在你已知的Android知識上創建新的應用。這部分內容主要是准備開發環境和開發TV應用的一些最低要求。(開發TV應用和手機應用本質是一致的,下面的一些要求只是你要使用到一些Google的庫(Leanback support)或者要將應用在GooglePlay上線,否則,要求不必遵守)
Supported Media Formats
DRM
android.drm
ExoPlayer
android.media.MediaPlayer
這一部分主要關於如何修改一個已存在的Android項目或者創建一個新的項目。
下面是讓app在電視設備上運行的主要部分:
1.Activity for TV,在manifest中聲明一個activity。
2.TV Support Libraries
1.SDK tools version 24.0.0 或者更高
2.SDK with android5.0 或者更高
3.創建或更新項目(如果你要修改已存在的Android項目應該是該項目的target為5.0或者更高)
可以兼容到API17
如果一個應用打算運行在電視設備上它必須在manifest文件中聲明一個TV activity。如下:
如果設置required屬性為true,你的APP在設備上將只運行leanback ui。
運行在TV設備上的應用不需要通過觸摸屏幕來輸入。
v17 leanback library 為電視應用程序提供用戶界面部件,特別是用於媒體播放的應用程序。
v7 recyclerview library
v7 cardview library
在完成上述步驟之後,是時候開始為大屏幕構建應用程序了!檢查這些額外的主題,以幫助您建立您的應用程序的電視:
構建電視播放應用
幫助用戶搜索內容
Building TV Games
Building TV Channels
㈢ Android TV-電視開發知識點速覽
原文鏈接: Android-Tv
本文總結 Android-TV 開發過程中,常見的基礎知識點。主要分為TV-UI,IPTV,OTT,DVB,TVOS,DEBUG等幾大模塊展開。適用於常見盒子,電視,投影儀等TV開發。
開局一張圖,直接上腦圖
Android TV 界面開發有別與傳統的移動手機端開發,TV端的交互主要是有用戶遙控器操作完成,因而在TV上按鍵和焦點的處理顯得尤為重要,其次TV端的輸出顯示媒介主要是電視顯示屏,不同的電視所能支持的輸入顯示解析度也不一樣,因而解析度的適配也是TV界面開發需要考慮的一點,除此之外TV界面的設計也與手機上的小屏顯示不一樣,由於是大屏顯示,對UI的設計需更加偏平話,便捷化。
IPTV概念的普及,國內主要靠電信,聯通,移動,廣電四大寬頻運營商。IPTV主要特點如下:
OTT的概率,國內主要靠互聯網行業推動,類似小米/樂視電視,盒子,創維,康佳,海信等智能電視。OTT主要特點如下:
DVB的概念,存在時間最早,即傳統的廣電業務。DVB系統按照信號傳播的順序可以分成前端系統,傳輸系統和終端系統。其中前端系統一般位於節目生產部門(例如電視台等部門),而終端系統一般用戶設備中(例如機頂盒)
區別於傳送方式的不同,DVB的通用國際標准又可以分為以下:
DVB標准中描述的系統根據所屬的層次不同從上層到底層可以分為:音視頻編碼層,服務信息層,基帶傳輸層,信道編碼層,射頻層。對於Android開發而言,主要涉及的為服務信息層。服務信息層主要分為:
PSI信息由節目關聯表PAT、條件接收表CAT、節目映射表PMT和網路信息表NIT組成,這些表會被插入到TS流中。 PSI信息是對單一TS流的描述,它是TS流的引導信息;PSI信息指定了如何從一個攜帶多個節目的傳輸流中找到指定的節目。 下面給出的是節目引導信息(或稱節目特定信息,PSI)的四個表結構
PSI只提供了單個TS流的信息,使接收機能夠對單個TS流中的不同節目進行解碼; 但是,它不能提供多個TS流的相關業務,也不能提供節目的類型、節目名稱、開始時間、節目簡介等信息。 因此,DVB對PSI進行了擴展,提供了其他不同類型的表,形成了SI。
SI定義的表,並不需要全部傳輸, 其中,SDT、EIT和TDT是必須傳輸的; 而又以SDT和EIT最為重要,利用這2個表可以構成功能不同的EPG, 如提供節目附加信息、節目分類、節目預定和家長分級控制等。
S 業務I信息表分為以下幾類:
DVB的搜台從用戶角度來說,一般可以分為自動搜台,全頻點搜台,手動搜台。其中手動搜台實質是單頻點搜台,自動搜台是檢索到ts流裡面的頻點信息後,還是回到單頻點搜台,全頻點搜台一般是固定了頻率的數組,依次掃描單頻點。
機頂盒搜台的實質是從TS流中獲取並存儲每套節目的音視頻PID值和構建出電子節目節目指南。
以下總結三種搜台實現流程:
播放主要分為大屏播放以及畫中畫播放,一直搞不懂為啥還要有畫中畫這種業務場景的需求。畫中畫一般需要雙demux支持。
dvb的播放流程與傳統的播放器調用有所差別,一般需要底層,jni層封裝單獨的播放器介面調用。
dvb播放需傳入頻點信息,音視頻pid,以及音視頻類型等。
先看下官方簡介-NGB TVOS,全稱Next Generation Broadcasting Network TVOS,是中華人民共和國國家新聞出版廣電總局科技司帶頭研發的基於Linux和安卓系統的一套應用於網路電視的操作系統。其開發者自稱「兼顧現有操作系統的技術,比如Linux、安卓」,並增加信息安全模塊,加強用戶的信息安全保障,是專門針對電視終端的操作系統。
根據以上描述,結合NGB相關規范,不難看出,TVOS其實還是基於Android系統開發改造,主要是通用規范了中間層介面規范,為硬體軟體廠家集成通用介面。
一套完整的TVOS系統,基本集合了DVB+IPTV的業務功能。TVOS應用層面基本覆蓋如下幾個方面
TV端的開發調試工作,與手機端也有些差異,TV端調試方式大致如下: