相信很多刚接触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端调试方式大致如下: