- 浏览: 325628 次
- 性别:
- 来自: 上海
文章分类
最新评论
-
xuanyuanxiaoxue:
...
Android - LayoutInflater -
柴兴博:
不错 多谢
Android 悬浮Activity并可拖动(访悬浮歌词) -
di1984HIT:
写的很好,我收藏一下。
java之动态代理模式(JDK和cglib) -
chinacssnj:
待测试,明天测,测试的结果发给大家
网络开发上传文件到服务器 -
fx_199182:
...
Android之MediaPlayer
第八章 Android GWES
8.1 View System
View & ViewGroup
Android的
UI系统是建立在View和ViewGroup之上的。View是组成UI基本部件,而ViewGroup可以把它看做Panel,就是容器。可以把
View和ViewGroup放到一个ViewGroup里布局,这些View和ViewGroup就组成了显示UI的树形结构(下图)。
Activity创建的Window中的主View既DecorView继承自FrameLayout,而FrameLayout又继承自
ViewGroup,这个DecorView就是每个Activity最最根部的那个ViewGroup。
View在Android中不单纯只是
负责显示功能,它还封装了UI
Event的处理功能。在系统中所有要显示的UI元素都继承自View(Surface除外),用户可以使用Android中已实现的一些View的子
类,这些子类包括TextView,Button等,在这里叫他们widget,这些widget都继承自View,但都他们各自的UI表现形式,以及对
UI
Event的不同处理方式。当然如果用户觉得这些widget无法满足的话,可以自定义View,既用户去实现一个继承了View的类,也可以继承
widget,并对View的相关成员函数进行重写,如OnDraw。
UI Event
View中以接口的形式定义一些类UI Event处理,其实接口里就是定义了一个回调函数,共使用者去实现,当有消息来时,就会调用到使用者实现的回调函数里。
参
考View.java public void setOnTouchListener(OnTouchListener l) {
mOnTouchListener = l; } public interface OnTouchListener { boolean
onTouch(View v, MotionEvent event); }
public boolean
dispatchTouchEvent(MotionEvent event) { if (mOnTouchListener != null
&& (mViewFlags & ENABLED_MASK) == ENABLED &&
mOnTouchListener.onTouch(this, event)) { return true; } return
onTouchEvent(event); }
参考usr.java usrTouchView. setOnTouchListener(new OnTouchListener{ onTouch() { TODO:: } })
关于消息是如何传递到dispatchTouchEvent的,在输入消息处理那一块会有详细介绍。
Graphics
上
面介绍了View是如何处理UI
Event,接下来会介绍View是如何显示出来,既画出来的。前面提到过View的OnDraw函数,可以说View的所有显示都在OnDraw里面,
每当View需要刷新时,都会调用的OnDraw,它的函数声明如下: protected void onDraw(Canvas canvas)
每
一个View的子类,包括widget都对它重写,这个函数的重点就是Canvas,所有显示的画图动作都是通过该类来实现的。它位于
android.Graphics的package内,Canvas提供一些类画图的方法,如drawPath(Path path, Paint
paint)。使用Canvas画图还需要一些其他资源
Bitmap:用于承载pixel,既所画的内容
Path:Region提供画的区域
Paint:描述颜色及样式
参
考Canvas.java public void drawPath(Path path, Paint paint) {
native_drawPath(mNativeCanvas, path.ni(), paint.mNativePaint); };
private static native void native_drawPath(int nativeCanvas, int path,
int paint);
从上面的代码片段了解到Canvs的这些画图方法,最后都是调用相对应的native API。这些native API到底层的调用流程是Skia/OpenGL====>SurfaceFlinger=====>framebuffer。
8.2 Android窗口管理
Activity如何启动的?
系
统初始化时会启动一系列服务,这其中包括Activity Manager Service和Window Manager
service,这些Service属于常驻程序,应用的进程可获得Service的本地代理来与Service进行通信,一般通过Binder或
AIDL接口。
Activity启动首先要程序的进程跑起来,而一个应用程序的主线程的启动时通过AMS(Activity Manager
Service的缩写)创建Activity
Thread对象,并由该对象来创建进程的主线程,通过AMS的request调度该进程的Activity。并且会创建消息循环Looper来实现消息
的分发。
下图是介绍ActivityThread中的ActivityRecord与AMS中HistoryRecord联系。
ActivityThread
的成员变量mActivities是个数组,用来保存该进程中的所有的Activity,并以ActivityRecord形式存在,而在AMS中也同样
有个mHistory数组来管理所有的Activity。这个mHistory保存的是HistoryRecord类,HistoryRecord中有
token,taskid。Taskid标示是哪个task, token标示哪个Activity。
Activity启动流程
1. 发起请求startActivity(intent)
2. Activity Service Manager接收到请求执行StartActivity函数。
3. 通过app.thread.scheduleLaunchActvity在App应用中建立新的ActivityRecord。
4. 建立新的Activity对象并放入到ActivityRecord中。
5. 将ActivityRecord加入到mActivites@ActivityThread
6. 发起Activity.onCreate(..),,该onCreate就是在你的应用程序XXXActivity中的onCreate。
窗口的基本框架
Activity建立一个主窗口后,在将主窗口添加到WindowManager时,首先要建立
WindowManager
代理对象,并打开一个会话(实现IWindowSession
AIDL接口),并维持该会话。Activity将通过该会话与WindowManager建立联系,这个Session是C/S体系的基
础,Client通过WindowSession将window加入到Window
Manager中。客户端的Activity通过Session会话与WindowManager建立对话,而WindowManager则通过
IWindow接口访问Client,将消息传递到Client端,通过消息分发渠道,将消息传递到处理函数OnXXX。
在
ActivityThread调用performLaunchActivity时,会使用Activity.attach()建立一个
PhoneWindow主窗口。这个主窗口的建立并不是一个重点。当ActivityThread调用handleResumeActivity去真正启
动一个Activity时候,将主窗口加入到WindowManager,当然并不是将主窗口本身,而是将主窗口的DecorView加入到
WindowManager中。DecorView实际上是一个ViewGroup,DecorView是Top-Level View。
下图描述的是如何将窗口的主View既DecorView添加到window manager
图
中在添加DecorView到WM中时,会创建一个ViewRoot,每个窗口(DecorView)都会对应一个ViewRoot,他是整个View树
形结构的根,ViewRoot实际是一个Handler,View
Tree消息的发送和处理都是从他开始。ViewRoot是建立主View与WindowsManger通讯的桥梁。ViewRoot与Window
Manager之间的联系是IWindowSession和IWindow。ViewRoot通过IWindowSession添加窗口到Window
Manager。而IWindow这是Window Manager分发消息
给Client ViewRoot的渠道。IWindowSession和IWindow都是AIDL接口,窗口与Window Manager Service就是利用这两个AIDL接口进行进程间通信。
消息机制Looper,Handle,MessageQueue
Looper只是产生一个消息循环框架,首先Looper创建了MessageQueue并把它挂接在Linux的线程上下文中,进入到取消息,并分发消息的循环当中。
Handle对象在同一个线程上下文中取得MessageQueue,最主要的就是SendMessage和担当起dispatchMessage这个实际工作。
MessageQueue就是消息队列,用来存放消息。
消
息的产生及处理流程(见上图),首先在应用程序启动时会创建ActivityThread对象来启动主线程,并管理当前应用所有的Activity,保存
到mActivities数组中(详细介绍见Activity启动介绍),在ActivityThread里会创建一个Looper对象,既该线程的所有
Activity都共用一个消息循环,Looper里会创建MessageQueue来存放Msg,Looper对象创建成功后,会调用Looper的静
态成员函数loop()开始消息循环,该静态函数中会获得当前线程的Looper对象,并从该Looper的MessageQueue中
GetMessage,获得的msg对象有个target的成员变量,该target就是要处理该msg的Handle对象,如果target为
null,则代表终止该消息循环,否则调用该handle的dispatchmessage,该函数中会调用handlemessage回调函数,该函数
会对消息进行处理,每个创建的handle对象要对handlemessage进行重写。如ViewRoot的handlemessage就是分发到
Focus View的OnXXX()。
但是消息是如何放到MessageQueue中的呢?下面介绍一下Handle类,就是刚才提到的msg
中的target域,该类中包括handlemessage,dispatchmessage以及一系列sendmessage函数,前两个函数的应用场
景前面已经讲过了。这一系列SendMessage就是最后都会调用sendMessageAtTime(),这个函数就是把发送的消息放到当前消息循环
的MessageQueue中。
对输入事件如何响应?
系统中与用户交互的程序,都是用户使用输入设备(鼠标,键盘,触控板),然后由这些
设备的驱动获得输入,并生成Event,放到Event队列中。上层的Window Manager
Service会通过Native函数来读取这些Event,并分发到具体的Focus View上。
1、 输入事件的收集
WindowMangerService
启动时会创建一个KeyQ对象mQueue,这是一个消息队列,继承自抽象类KeyInputQ,在KeyInputQ中建立一个独立的线程
InputDeviceReader,使用Native函数readEvent来读取Linux Driver的数据构建Raw
Event,放到KeyQ消息队列中。
2、 消息分发到Focus Window
WMS(Window Manager
Service)有InputDispatcherThread的线程,该线程循环的从mQueue中获得Raw Events,并根据Event
Type分别调用不通dispatch函数(dispatchKey, dispatchPointer,
dispatchTrackball),在WMS的dispatch找到中的Focus
Window,下面的代码片段中WindowState,是Client端Window在WMS端的对应对象,通过WindowState记录的
mClient(IWindow)接口,将Events专递到Client端。 //InputDispatcherThread
DispatchKey() { Object focusObj =
mKeyWaiter.waitForNextEventTarget(event, null, null, false, false, pid,
uid); 。。。 WindowState focus = (WindowState)focusObj; 。。。
Focusobj.mClient.dispatchKey(event) 。。。 }
3、 应用消息队列分发
通过上面窗口的框架介绍,
我们了解到WindowState中mClient既IWindow接口,是WMS同Activity的Window沟通的接口,通过该接口把event
发到Focus
Window的ViewRoot对象,ViewRoot继承自Handle,ViewRoot中的dispatchKey会调用SendMessage,
把该Event发到当前线程的消息队列里,最后会调用到ViewRoot重写handlemessage。
4、 通过FocusPath,发到FocusView
ViewRoot的handlemessage函数找到他对应DecorView并,按下图所示的Focus Path会最终传递到要处理该事件的view上,并调用相应的回调处理函数,如OnClick()。
转自:http://blog.csdn.net/googleandroider/article/details/6580929
发表评论
-
Android中AsyncTask的简单用法
2012-01-13 16:00 1127在开发Android移动客户端的时候往往要使用多线程来进行操 ... -
Android应用的自动升级、更新模块的实现 .
2011-11-16 14:01 647http://www.eoeandroid.com/threa ... -
一个APK反编译利器Apktool
2011-11-16 13:54 1557一个APK反编译利器Apktool APK 本地化 ... -
自定义Android标题栏TitleBar布局
2011-11-14 14:13 1218很多网友发现自己Android程序的标题栏TitleBar区域 ... -
Android GPS获取地理位置 .
2011-11-14 14:11 829import android.app.Activity; i ... -
android ListView详解
2011-11-14 13:48 1026在android开发中ListView是比较常用的组件,它以列 ... -
Android之Content provider 详解
2011-11-14 13:35 2437Android是如何实现应用程序之间数据共享的?一个应用程序可 ... -
Android源码地址
2011-11-12 19:14 1027http://blog.csdn.net/ilittleone ... -
android之File
2011-11-11 22:39 19701:Fileservice package cn.itcas ... -
Android知识补漏
2011-11-09 22:33 01:AndroidManifiest.xml < ... -
深入剖析Android消息机制
2011-11-09 14:13 936在Android中,线程内部或者线程之间进行信息交互时经常会使 ... -
Android之Handler详解(四)
2011-11-09 14:00 1263d、自己创建新的线程,然后在新线程中创建Looper,主线程调 ... -
Android之Handler详解(三)
2011-11-09 13:58 1349c、将消息队列绑定到子线程上,主线程只管通过Handl ... -
Android之Handler详解(二)
2011-11-09 13:54 1635二:sendMessage版本的Handl ... -
Android之Handler详解(一)
2011-11-09 13:22 2270一个Handler允许你发送和处理消息(Message)以及 ... -
关于StartActivityForResult方法的使用
2011-10-31 17:11 1058根据方法名可知 这个方法是要得到启动后的Activity返回的 ... -
Android 悬浮Activity并可拖动(访悬浮歌词)
2011-10-24 16:23 2054天天动听, 这款Android手机上的音乐播放器,相信不少朋友 ... -
Android系统服务-WindowManager
2011-10-24 16:10 1416WindowManager是Android中一个重要的服务 ... -
http通信
2011-10-15 17:31 1068HTTP(HyperText Transfer Proto ... -
android网络与通信(三种网络接口简述 )
2011-10-15 17:27 1413标准Java接口 java.net.*提供与联网有关的类 ...
相关推荐
总结Android GWES基本原理
Android 核心分析(13) -----Android GWES之Android窗口管理
Android核心分析 之十一-------Android GWES之消息系统
核心分析之十三 ----- Android GWES之Android窗口管理 核心分析之十四 ----- Android GWES之输入系统 核心分析之十五 ----- Android 输入系统之输入路径详解 核心分析之十六 ----- Android 电话系统-概述篇 核心...
Android核心分析(13)----Android GWES之Android窗口管理 Android核心分析(14)----Android GWES之输入系统 Android核心分析(15)----Android输入系统之输入路径详解 Android核心分析(16)----Android电话系统-...
Android核心分析(13)----Android GWES之Android窗口管理 Android核心分析(14)----Android GWES之输入系统 Android核心分析(15)----Android输入系统之输入路径详解 Android核心分析(16)----Android电话系统-...
Android 核心分析(13) -----Android GWES 之 Android 窗口管理............................... 50 Android 核心分析(14)------ Android GWES 之输入系统..........................................57 Android 核心...
Android核心分析之十-------AndroidGWES之基本原理篇.......................................40 Android核心分析之十一-------AndroidGWES之消息系统.......................................43 Android核心分析(12...
Android 核心分析(13) -----Android GWES 之Android 窗口管理............................... 50 Android 核心分析(14)------ Android GWES 之输入系统..........................................57 Android ...
Android 核心分析 (13) -----Android GWES 之 Android 窗口管理 ............................... 50 Android 核心分析( 14 ) ------ Android GWES 之输入系统 .......................................... 57 ...
[转]Android核心分析 技术专题之十一--Android GWES之消息系统
Android 核心分析 技术专题之十三--Android GWES之Android窗口管理
第一章 Android开发环境 第二章 Android基础知识 ...第八章 Android GWES 第九章 Android安全机制 第十一章 Android内核驱动——Alarm 第十三章 Android内核驱动——电源管理 第十四章 Android内核驱动——内存管理
[转]Android核心分析 技术专题之十--Android GWES之基本原理
[转]Android核心分析 技术专题之十四--Android GWES之输入系统.
Android_GWES~~~~~~~~~~~~~~~~~~