1.Androidä¸Viewçå建è¿ç¨
2.Android 14 HWUI 源码研究 View Canvas RenderThread ViewRootImpl skia
3.车机开发Android SystemUI 架构音量控制详解
4.android onTouchEventåsetOnTouchListenerä¸onTouchçåºå«
Androidä¸Viewçå建è¿ç¨
æ们ç¥éå¨onCreateéé¢Viewè¿æ¯æ²¡ææµç»å®æçãé£ä¹ä»ä¹æ¶åæµç»å®æäºï¼çæ¡æ¯onResumeãéè¿æ¥çæºç æ们å¯ä»¥çå°å¨onCreateæ¹æ³éé¢è°ç¨äºgetWindow()æ¹æ³ç¶åå¨å°æ们ç页é¢å¡å°è¿ä¸ªwindowéé¢ãè¿ä¸ªwindowä¹å°±æ¯PhonwWindow.
é£PhoneWindowæ¯ä»ä¹æ¶å被å建çï¼
è¿å°±å¼åºäºActivityçå建æµç¨ã
é£Activityæ¯æä¹è¢«å建çå¢ï¼
ç±äºActivityæ¯ä¸ä¸ªç»ä»¶ä»æ¯ç±ç³»ç»ä½¿ç¨ActivityThreadæ¹æ³å»å建çã
ç°å¨ææ¥åæä¸ï¼
å æ¥å°ActivityThreadç±»çhandleLaunchActivityæ¹æ³ã
å¯ä»¥çå°ä»å»è°ç¨äºActivityçperformCreateæ¹æ³ã
ç°å¨æ们ç»äºçå°onCreateæ¹æ³è¢«è°ç¨äºã
è¿éè¿æ个éç¹ï¼å¨performLaunchActivityéé¢å»è°ç¨ActivityçonCreateæ¹æ³ä¹åè¿å»åäºä¸ä»¶å¾éè¦çäºæ ï¼è¿ä¸ªäºæ å¨ç¬¬è¡ï¼è°ç¨äºActivityçattachæ¹æ³ã
ç°å¨è·å°Activityçattachæ¹æ³ï¼æ¾å°äºæ们ä¸ç´æ¾çPhoneWindowçå建ã
Android HWUI 源码研究 View Canvas RenderThread ViewRootImpl skia
HUWUI是Android系统中负责应用可视化元素绘制的核心组件,其架构主要在C++层实现,从Java层接收View绘制信息,通过唯一的渲染线程使用skia技术完成渲染任务。整体上,从应用程序到UI线程,qqmake 3.0源码再到渲染线程,形成了清晰的层级关系。
HUWUI的构建主要包括三个核心类,它们分别是:RecordingCanvas、Canvas、RenderNode、RenderProxy、RenderThread、CanvasContext、添加人才信息表源码IRenderPipeline。在Java层,主要涉及两类Canvas,RecordingCanvas用于记录绘制指令,Canvas则是直接用于渲染。RecordingCanvas在构造时创建,而Canvas在调用时创建。这两个类在C++层分别对应SkiaRecordingCanvas和SkiaCanvas,后者直接引用SkCanvas。
在全局循环中,UI线程与渲染线程之间的协同操作至关重要。具体流程包括:新创建Activity后,附着到对应的PhoneWindow,然后调用PhoneWindow的安卓app源码打包apksetContentView方法,将View添加到DecorView作为子节点。接着,DecorView与ViewRootImpl对接,完成View的更新与渲染。整个过程包含了measure、layout和draw等复杂子流程。
渲染线程创建与核心对象紧密关联,主要包括RenderProxy、RenderThread和DrawFrameTask。RenderProxy负责Java层信息的衔接,RenderThread作为进程唯一的渲染线程,持有DrawFrameTask和CanvasContext,完成一帧的绘制任务。指令记录流程的蜗牛云电视小程序源码核心在于使用C++层的RecordingCanvas将View属性和绘制信息记录到DisplayList中,进而完成指令的渲染。
Surface、ANativeWindow、EGLSurface的创建流程在ViewRootImpl的performTraversals函数中初始化。ReliableSurface的封装和EGL与Skia环境的创建主要在RenderThread的requireGlContext函数中实现。从源码分析,这一过程通常在三个地方调用。
View树与RenderNode树之间的协作关系明确,一个Application进程对应多个Activity,每个Activity与一个PhoneWindow绑定,PhoneWindow持有DecorView,DecorView对应一个ViewRootImpl,而ViewRootImpl与ThreadedRender模块对接。ThreadedRender与C++层的新版盗U系统源码2022RenderProxy一一对应,RenderProxy持有关键对象,如RenderThread、CanvasContext、DrawFrameTask等。RenderThread是单例模式,进程唯一,负责一帧绘制的逻辑。
在RenderPipeline模块中,关键操作包括makeCurrent、draw和swapBuffers。Native Canvas在这一过程中扮演了桥梁角色,接收Java API调用,而RecordingCanvas完成Op记录,最终DisplayListData存储这些Op。
skia的核心资源主要在三个使用场景中发挥作用,具体细节需深入分析,这些资源对于实现高效、稳定的渲染效果至关重要。
车机开发Android SystemUI 架构音量控制详解
在Android系统中,SystemUI是一个特殊的应用,尽管它的源代码形式类似于普通应用,但它以独特的存在方式运行在系统内部。这个模块以APK文件的形式存在,位于`frameworks/base/packages/SystemUI/`目录下,并安装在`system/priv-app/-SystemUI`路径中。尽管它是一个应用,但它的界面和功能设计使得用户在使用过程中难以将其视为一个传统应用。
SystemUI的核心功能包括提供系统控制界面,例如音量控制、通知管理等。其中,音量控制模块(VolumeUI)在用户操作音量键时负责提供相应的用户界面,并允许设置音量大小和情景模式。VolumeUI的代码主要集中在`SystemUI/volume`目录下,不同模式下音量键触发的UI显示样式会有所不同,包括通话、铃声(通知)、音乐、闹铃、蓝牙输出等。
当音量键触发时,VolumeUI通过系统服务启动,主要经过初始化过程,包括读取配置、实例化UI控件、创建VolumeController控制器等步骤。初始化过程中的关键步骤包括实例化`VolumePanel`,这是一个`Handler`的子类,负责UI的绘制和控制。此过程以Dialog的形式显示UI,确保UI的交互性。`VolumePanel`同时继承了`VolumeUI`的`Pannel`,因此,它不仅负责显示,还控制了UI的显示和关闭。
VolumeUI的架构展示了如何在不同模式下控制音量。当非活动窗口接收到音量键事件时,这些事件通常在`Window`中被处理。系统通过Binder机制将事件信息传递给`MediaSessionService`,然后传递给`AudioService`,最后到达`SystemUI`的`VolumeUI`部分,使得音量控制响应用户操作。
在具体的音量控制过程中,当活动窗口为Launcher桌面时,音量键事件在`PhoneWindow`中被处理。事件分发到`onKeyUp()`和`onKeyDown()`方法,调用`sendAdjustVolumeBy()`方法来调整音量。这些事件最终传递到`MediaSessionService`,进一步通过Binder机制到达`AudioService`,完成音量调整的过程。
总结整个流程,从音量键触发到UI显示和关闭,涉及到多个系统服务和进程之间的通信。通过Binder机制确保了不同组件之间的高效通信和控制。整个控制过程直观且高效,为用户提供了一致且响应迅速的音量控制体验。
android onTouchEventåsetOnTouchListenerä¸onTouchçåºå«
触æ¸äºä»¶ååæºå¶ï¼å¥½å¥½ççï¼
/blog/
Androidä¸çäºä»¶å为æé®äºä»¶å触æ¸äºä»¶ï¼è¿é对触æ¸äºä»¶è¿è¡éè¿°ãTouchäºä»¶æ¯ç±ä¸ä¸ªACTION_DOWNï¼n个
ACTION_MOVEï¼ä¸ä¸ªACTION_UPç»æonClickï¼onLongClickï¼onScrollçäºä»¶ãAndroidä¸çæ§ä»¶é½æ¯ç»§æ¿
Viewè¿ä¸ªåºç±»çï¼èæ§ä»¶å为两ç§ï¼ä¸ç§æ¯ç»§æ¿Viewä¸è½å å«å ¶ä»æ§ä»¶çæ§ä»¶ï¼ä¸ç§æ¯ç»§æ¿ViewGroupå¯ä»¥å å«å ¶ä»æ§ä»¶çæ§ä»¶ï¼æä¸ç§°ä¸ºå®¹å¨æ§
件ï¼æ¯å¦ListViewï¼GridViewï¼LinearLayoutçã
è¿éå 对å 个å½æ°è®²è§£ä¸ã
Ø public boolean dispatchTouchEvent (MotionEventev) è¿ä¸ªæ¹æ³ååTouchEvent
Ø public booleanonInterceptTouchEvent(MotionEvent ev) è¿ä¸ªæ¹æ³æ¦æªTouchEvent
Ø public boolean onTouchEvent(MotionEvent ev) è¿ä¸ªæ¹æ³å¤çTouchEvent
å ¶ä¸viewç±»ä¸ædispatchTouchEventåonTouchEvent两个æ¹æ³ï¼ViewGroup继æ¿Viewï¼èä¸è¿æ°æ·»äºä¸ä¸ª
onInterceptTouchEventæ¹æ³ãActivityä¸ä¹æ onInterceptTouchEventæ¹æ³ï¼ä½æå¦å¤ä¸¤ç§æ¹æ³ãæ们å¯ä»¥
åç°ä¸é¢3个æ¹æ³é½æ¯è¿åbooleanï¼é£å代表ä»ä¹ææå¢ï¼
public boolean dispatchTouchEvent (MotionEvent ev)
Activityä¸è§£éï¼
Called to process touch screen
events.You can override this to intercept all touch screen events before
they aredispatched to the window. Be sure to call this implementation
for touch screenevents that should be handled normally.
Parameters
ev
The touch screen event.
Returns
· boolean Return true if this event was consumed.
å®ä¼è¢«è°ç¨å¤ç触æ¸å±äºä»¶ï¼å¯ä»¥éåè¦çæ¤æ¹æ³æ¥æ¦æªææ触æ¸å±äºä»¶å¨è¿äºäºä»¶ååå°çªå£ä¹åãé常åºè¯¥å¤ç触æ¸å±äºä»¶ï¼ä¸å®è¦è°ç¨è¿ä¸ªå®ç°ãå½è¿
åå¼ä¸ºtrueæ¶ï¼è¡¨ç¤ºè¿ä¸ªäºä»¶å·²ç»è¢«æ¶è´¹äºãä¾å¦å¨TextActivityä¸dispatchTouchEventå¨ACTION_MOVEè¿å
trueï¼è¿è¡ç»æå¦ä¸ï¼
ä¹å°±æ¯å®å¹¶æ²¡ææé£ACTION_MOVEååä¸å»ã
public boolean onInterceptTouchEvent (MotionEvent ev)
Implementthis
method to intercept all touch screen motion events. This allows you
towatch events as they are dispatched to your children, and take
ownership of thecurrent gesture at any point.
Usingthis function takes some care, as it has a fairly complicated interaction with View.onTouchEvent(MotionEvent),and
using it requires implementing that method as well as this one in
thecorrect way. Events will be received in the following order:
1. You will receive the down event here.
2. The
down event will be handled either by a child of this viewgroup, or
given to your own onTouchEvent() method to handle; this means youshould
implement onTouchEvent() to return true, so you will continue to see
therest of the gesture (instead of looking for a parent view to handle
it). Also,by returning true from onTouchEvent(), you will not receive
any followingevents in onInterceptTouchEvent() and all touch processing
must happen inonTouchEvent() like normal.
3. For
as long as you return false from this function, eachfollowing event (up
to and including the final up) will be delivered first hereand then to
the target's onTouchEvent().
4. If
you return true from here, you will not receive any followingevents:
the target view will receive the same event but with the action ACTION_CANCEL, and all further events will be delivered to youronTouchEvent() method and no longer appear here.
Parameters
ev
The motion event being dispatched down the hierarchy.
Returns
· Return
true to steal motionevents from the children and have them dispatched
to this ViewGroup throughonTouchEvent(). The current target will receive
an ACTION_CANCEL event, and nofurther messages will be delivered here.
åºæ¬ææå°±æ¯ï¼
1. ACTION_DOWNé¦å ä¼ä¼ éå°onInterceptTouchEvent()æ¹æ³
2.å¦æ该ViewGroupçonInterceptTouchEvent()å¨æ¥æ¶å°downäºä»¶å¤çå®æä¹åreturn falseï¼é£ä¹åç»çmove, upçäºä»¶å°ç»§ç»ä¼å ä¼ éç»è¯¥ViewGroupï¼ä¹åæådownäºä»¶ä¸æ ·ä¼ éç»æç»çç®æ viewçonTouchEvent()å¤çã
3.å¦æ该ViewGroupçonInterceptTouchEvent()å¨æ¥æ¶å°downäºä»¶å¤çå®æä¹åreturn trueï¼é£ä¹åç»çmove, upçäºä»¶å°ä¸åä¼ éç»onInterceptTouchEvent()ï¼èæ¯ådownäºä»¶ä¸æ ·ä¼ éç»è¯¥ViewGroupçonTouchEvent()å¤çï¼æ³¨æï¼ç®æ viewå°æ¥æ¶ä¸å°ä»»ä½äºä»¶ã
4.å¦ææç»éè¦å¤çäºä»¶çviewçonTouchEvent()è¿åäºfalseï¼é£ä¹è¯¥äºä»¶å°è¢«ä¼ éè³å ¶ä¸ä¸å±æ¬¡çviewçonTouchEvent()å¤çã
5.å¦ææç»éè¦å¤çäºä»¶çviewçonTouchEvent()è¿åäºtrueï¼é£ä¹åç»äºä»¶å°å¯ä»¥ç»§ç»ä¼ éç»è¯¥viewçonTouchEvent()å¤çã
Android touchäºä»¶ä¼ éæºå¶ï¼
æ们å¯ä»¥ççandroidæºä»£ç ï¼
Activity.javaä¸
æä¸ä¸ç®¡onUserInteractionæ¹æ³å 为å®åªæ¯ä¸ä¸ªç©ºæ¹æ³å¦æä½ æ²¡å®ç°çè¯ãgetWindow().superDispatchTouchEvent(ev)ãå ¶ä¸getWindow()è¿åçæ¯PhoneWindowã
PhoneWindow.java:
æ¤å½æ°è°ç¨super.dispatchTouchEvent(event),Activityçrootviewæ¯
PhoneWindow.DecorView,å®ç»§æ¿FrameLayoutãéè¿super.dispatchTouchEventætouchäºä»¶æ´¾
åç»å个Activityçæ¯åviewãåæ¶æå¯ä»¥çå°ï¼å¦æåviewæ¦æªäºäºä»¶ï¼åä¸ä¼æ§è¡onTouchEventå½æ°ã
ViewGroup.javaä¸dispatchTouchEventæ¹æ³ï¼
ç±äºä»£ç è¿é¿è¿éå°±ä¸è´´åºæ¥äºï¼ä½ä¹ç¥éå®è¿åçæ¯
return target.dispatchTouchEvent(ev);
è¿étargetæçæ¯æååçç®æ ï¼å¯ä»¥æ¯å®æ¬èº«ï¼ä¹å¯ä»¥æ¯å®çåViewã
ViewGroup.javaä¸çonInterceptTouchEventæ¹æ³ï¼
é»è®¤æ åµä¸è¿åfalseãå³ä¸æ¦æªtouchäºä»¶ã
View.javaä¸çdispatchTouchEventæ¹æ³
è¿éæ们å¾æ¸ æ¥å¯ä»¥ç¥éå¦æifæ¡ä»¶ä¸æç«ådispatchTouchEventçè¿åå¼æ¯onTouchEventçè¿åå¼
View.javaä¸çonTouchEventæ¹æ³