标签:区别 view 程序猿 这一 awb 文件夹 content 操作系统 字节
优秀程序猿的天性就是好奇,软件是怎么运作的、屏幕是怎样显示的、桌面窗口为何能如此人性化的被鼠标拖动?
假设你常常会有这样一些问题迸发在脑海中,恭喜你,你是一名非常有潜力的程序猿。
我在大学读的是自己主动化专业,属于电子类,再者对计算机相当感兴趣,第一次看到这玩意时,就认为这东西太奇妙了(事实上当时仅仅要看到有屏幕的东西,都认为非常奇妙)。硬件+软件的深入让我直接打通了了解这一神奇机器的任督二脉。
软件我不是最牛逼的,硬件事实上我非常歇菜。可是透过硬件看软件预计我还有那么一点点发言权。以下相关内容是个人小小的感性认识,希望能对大家有一定启示。由于个人从毕业至今做了约2年安卓,所以就拿安卓来看吧。
安卓属于操作系统(下面简称os),执行于硬件之上,os上可搭载app,app基于os暴漏的api编写。编写安卓程序时,你会看到程序引用了android.jar(这玩意在"ad文件夹\sdk\platforms\android-17"下,约18.2M),程序之中用到的大部分api都在这里(如:activity),可是一个奇怪的现象时,编译的apk中并没有这玩意,一个简单的demo编译的apk仅仅有几M。可是假设引用第三方类库(如libs中导入jar包、引用外部包)时,编译的apk中就会包括该jar包,而且体积增大。这是由于android.jar中的代码已经存在于操作系统内了(不一定叫android.jar,且分散在多个jar中),而写代码时用的android.jar主要作用是用来做编译时检查、支持代码提示、跳转至源代码,android.jar就是一个编程范本。
ok,编写完最小demo后,就能够执行在安卓手机上了,一小段代码就可以显示非常丰富的界面、button、点击处理。
可是这一小段代码脱离os是无法运作的,简单的效果背后是庞当的体系在作支撑。
比方显示,xml编写的布局文件,执行时会被翻译成java,类、属性、结构层次一一相应(所以xml写的东西一般能全然用java替代)。
显示的视图大部分基于View,View.draw负责该View的所有绘制,你所示button的默认背景以及点击效果是系统自带的png图片。可是View.draw究竟是谁调用呢,假设打断点调试,会发现层次非常的,从外向内调,非常easy看晕(断点找机制这样的事要长期磨练,非一日之寒)。断点能看到终于发起者是Choreographer(这玩意负责"绘制/事件"等的"发起"),那Choreographer又是被谁驱动去"发起绘制"的呢,ActivityThread,ActivityThread是apk每帧运作的根源。了解GUI编程的同学知道,程序看是没有运作,可是能够响应点击,是由于app在一直监视着你,这样的监视叫"消息循环"(说白了,就是个死循环),这个死循环一直在推断有没有消息(你能够简单的把它理解为一个标志位)到来(比方点击),假设有有就分支回调相应处理函数。
ok,Choreographer是怎样被驱动的就又清晰了一步,有人向ActivityThread的消息循环的投了一个"绘制消息"。
可是这个消息是哪来的呢。程序第一次执行时,会主动抛一个(你能够假想在程序初始化中抛),执行时,各种点击、动画都会抛(类似view.invalidate的东西),触发又一次绘制。
ok,绘制触发的根源大概也追踪到了一定程度。可是视图是怎样显示在屏幕上的呢,尽管view.draw中能够非常清晰的看到用canvas画了写什么东西(如最经常使用的canvas.drawBitmap),可是canvas的这些draw究竟是怎么传送到屏幕上的呢。
这一段根源我临时还没探究过源代码,可是毕竟搞过arm,手动驱动过显示屏,这里仅仅做大致推測,基本原理应该差不到哪去。
基本思路是,app绘制→os→驱动→硬件,哈哈,貌似全部和硬件相关的终于机制都是这样。
驱动是直接和硬件打交道的,通常是汇编或c编写,直接控制硬件接口,一般被称为hal(硬件抽象层)。os作用中间桥梁。
canvas含一块bitmap(相应一块内存),canvas的各种draw会形成像素矩阵(屏幕像素点的描写叙述)存在bitmap内,经过os传递给驱动,驱动直接驱动屏幕。此间的细节代码、机制相当繁琐。但理论上,图像描写叙述在内存中,基本上就能够显示出来了,那bitmap这块内存是怎样会显示出来的呢?
有一块内存叫"显存"(是不是非常熟悉,台式机的显存一般可放在显卡中,事实上放哪都是块内存),顾名思义,显存就是用来显示的内存。基本原理是,驱动用两个for(行列)扫描显存,读取每一个像素,将单个像素信号设置到相应屏幕的一个点上。两个for就是一个面了。可是这单个像素信号是怎么设置到屏幕单点上的呢?这里我们能够在将单点简化为"电灯泡",仅仅有两种颜色(白+黑),灯泡接在主板的一个io接口上,io口上电,灯就亮。断掉,灯就黑。驱动的代码依据显存中单点数据,控制io接口的上断电就可以。
ok,复杂一点,如今的屏幕颜色是RGB(0xffffff表白色,ARGB中alpha仅仅是用来给多个层运算混合,终于显示的还是RGB)。
一个屏幕点事实上由三个点(红/绿/蓝)组成(贴近你家的电视会看得比較清楚)。每一个点的强弱从不亮到最亮划分等级,用一个字节表示(0x00~0xff,即0~255,共256级),一个点接8个io接口就能够控制了,驱动控制8x3个io口就能够显示一个点的全部颜色了。
是不是清晰很多了。
可是一个屏幕有这么多点(1024x768=69632),芯片虽小,但也不可能有这么多接口吧。
玩过嵌入式的同学知道,一般接一个显示屏,应该不会超过50根线(应该比这少的多,记得不是非常清晰)。刚才说过驱动的绘制通常是用两个for一个点一个点的扫的,所以理论上暴漏一个点的接口(8x3个)就能够了(实际稍有区别),可是屏幕怎么知道这一个点是绘制在哪一个实际点上呢?
主板、屏幕通过约定好的时序同步进行就能够了(加几条同步信号接口,表示哪行哪列)。
这次大概就漫游到这里吧,穷追不舍不是为了死砖牛角尖,而是一步步验证自己的思路,锻炼自己的左脑。安卓中结构最好的源代码莫过于andorid-os,那是凝聚力多少思维的结晶。
标签:区别 view 程序猿 这一 awb 文件夹 content 操作系统 字节
原文地址:http://www.cnblogs.com/yutingliuyl/p/6792110.html