安卓知识总结---(安卓基础)

一、handler的原理

子线程向主线程发送消息

子线程向子线程发送消息

想往那个线程里传递消息,就调用这个线程的hander,比如想往主线程里塞消息,就调用主线程的hander,想往子线程里塞消息,

就调用子线程的hander,hander里包含了looper的queue对象,通过调用这个queue,把消息塞到要调用的线程的队列里,每个线程的队列都是for循环,所以就能收到这个对象。

ThreadLocal,是一个static的变量,用来保存每个线程的Looper信息,方便外界直接获取当前线程的Looper

Looper不会卡死,因为线程会挂起

二、进程之间的通信

 进程间通信

1、Bundle/Intent传递数据:

可传递基本类型,String,实现了Serializable或Parcellable接口的数据结构。Serializable是Java的序列化方法,Parcellable是Android的序列化方法,前者代码量少(仅一句),但I/O开销较大,一般用于输出到磁盘或网卡;后者实现代码多,效率高,一般用户内存间序列化和反序列化传输。

文件共享:

对同一个文件先后写读,从而实现传输,Linux机制下,可以对文件并发写,所以要注意同步。顺便一提,Windows下不支持并发读或写。

2、Messenger:

Messenger是基于AIDL实现的,服务端(被动方)提供一个Service来处理客户端(主动方)连接,维护一个Handler来创建Messenger,在onBind时返回Messenger的binder。

双方用Messenger来发送数据,用Handler来处理数据。Messenger处理数据依靠Handler,所以是串行的,也就是说,Handler接到多个message时,就要排队依次处理。

3、AIDL:

AIDL通过定义服务端暴露的接口,以提供给客户端来调用,AIDL使服务器可以并行处理,而Messenger封装了AIDL之后只能串行运行,所以Messenger一般用作消息传递。

通过编写aidl文件来设计想要暴露的接口,编译后会自动生成响应的java文件,服务器将接口的具体实现写在Stub中,用iBinder对象传递给客户端,客户端bindService的时候,用asInterface的形式将iBinder还原成接口,再调用其中的方法。

4、ContentProvider:

系统四大组件之一,底层也是Binder实现,主要用来为其他APP提供数据,可以说天生就是为进程通信而生的。自己实现一个ContentProvider需要实现6个方法,其中onCreate是主线程中回调的,其他方法是运行在Binder之中的。自定义的ContentProvider注册时要提供authorities属性,应用需要访问的时候将属性包装成Uri.parse("content://authorities")。还可以设置permission,readPermission,writePermission来设置权限。 ContentProvider有query,delete,insert等方法,看起来貌似是一个数据库管理类,但其实可以用文件,内存数据等等一切来充当数据源,query返回的是一个Cursor,可以自定义继承AbstractCursor的类来实现。

5、brocast:

android中的广播可以可以拿来跨进程通信

6、Socket:

学过计算机网络的对Socket不陌生,所以不需要详细讲述。只需要注意,Android不允许在主线程中请求网络,而且请求网络必须要注意声明相应的permission。然后,在服务器中定义ServerSocket来监听端口,客户端使用Socket来请求端口,连通后就可以进行通信。

僵尸进程:子进程结束后,父进程要负责对子进程进行回收,否则就会变成僵尸进程

三、安卓图形绘制和渲染

GPU 主要用于处理图形运算,可以加快栅格化的过程。

对于硬件绘制,Android 使用 OpenGL 在 GPU 上完成,OpenGL 是扩平台的图形 API,为 2D/3D 图形处理硬件制定了标准的软件接口。软件绘制使用的是 Skia 库,它能在低端设备上呈现高质量的 2D 跨平台图形。

绘制流程:

  • 画笔:Skia 或者 OpenGL。我们可以用 Skia 画笔绘制 2D 图形,也可以用 OpenGL 来绘 制2D/3D图形。正如前面所说,前者使用CPU绘制,后者使用 GPU 绘制。

  • 画纸:Surface。所有的元素都在 Surface 这张画纸上进行绘制和渲染。在 Android 中,Window 是 View 的容器,每个窗口都会关联一个 Surface。而 Windowmanager 则负责管理这些窗口,并且把它们的数据传递给 Surfaceflinger。

  • 画板:Graphic Buffer。Graphic Buffer 缓冲用于应用程序图形的绘制,在 Android 4.1 之前使用的是双冲机制;在 Android 4.1 之后,使用的是三缓冲机制。

  • 显示:Surfaceflinger。它将 Windowmanager 提供的所有 Surface,通过硬件合成器 Hardware Composer 合成并输出到显示屏。

硬件加速:

硬件加速绘制与软件绘制整个流程差异非常大,最核心就是我们通过 GPU 完成 Graphic Buffer 的内容绘制。此外硬件绘制还引入了ー个 Display List 的概念,每个 View 内部都有个 Displaylist,当某个 View 需要重绘时,将它标记为 Dirty。

当需要重绘时,仅仅只需要重绘一个 View 的 Display List,而不是像软件绘制那样需要向上递归。这样可以大大减少绘图的操作数量,因而提高了渲染效率。

硬件加速大大提高来 Android 系统显示和刷新的速度,但是也存在一些问题:一方面内存消耗,OpenGL API 和Graphic Buffer 缓冲区占用内存。还存在兼容性问题。

Android 7.0 把 OpenGL ES 升级到最新的 3.2 版本同时,还添加了对Vulkan的支持。Vulkan 是用于高性能 3D 图形的低开销、跨平台 API。相比 OpenGL ES,Vulkan 在改善功耗、多核优化提升绘图调用上有着非常明显的优势。

四、VIew的事件分发机制

事件分发关于三个方法,dispatchTouchEvent,onTouchEvent和onInterceptTouchEvent

五、View的绘制流程

测量是View测量好自己的大小,再调用子View去测量自己的大小,层层调用

布局也是当前View布局完之后,再调用子View进行布局。

六、View 和SurfaceView

SurfaceView继承于VIew,可以在子线程里更新UI,

由于是在新的线程中更新画面所以不会阻塞你的UI主线程。但这也带来了另外一个问题,就是事件同步。比如你触屏了一下,你需要surfaceView中thread处理,一般就需要有一个event queue的设计来保存touch event,这会稍稍复杂一点,因为涉及到线程同步

SurfaceView的挖洞原理,独立的windows

第1步,SurfaceView将通过IWindow接口与WindowManagerService关联,WindowManagerService服务将认为Activity窗口和SurfaceView的地位是一样的,即认为它们各自拥有独立窗口,并且具有绘图表面surface; 
第5步,ViewGroup的gatherTransparentRegion方法遍历包括SurfaceView在内的所有子View的gatherTransparentRegion以得到最后的透明区域TransparentRegion,如果其他类型子View覆盖SurfaceView,其gatherTransparentRegion方法将减去相应透明区域。同理,在绘制的过程中,ViewGroup的dispatchDraw也将遍历所有子View的draw,覆盖SurfaceView的子View也将绘制在SurfaceView之上。

为了接下来可以方便地描述SurfaceView的实现原理分析,我们假设在一个Activity窗口的视图结构中,除了有一个DecorView顶层视图之外,还有两个TextView控件,以及一个SurfaceView视图,这样该Activity窗口在SurfaceFlinger服务中就对应有两个Layer或者一个Layer的一个LayerBuffer,

在图1中,Activity窗口的顶层视图DecorView及其两个TextView控件的UI都是绘制在SurfaceFlinger服务中的同一个Layer上面的,而SurfaceView的UI是绘制在SurfaceFlinger服务中的另外一个Layer或者LayerBuffer上的。

注意,用来描述SurfaceView的Layer或者LayerBuffer的Z轴位置是小于用来其宿主Activity窗口的Layer的Z轴位置的,但是前者会在后者的上面挖一个“洞”出来,以便它的UI可以对用户可见。实际上,SurfaceView在其宿主Activity窗口上所挖的“洞”只不过是在其宿主Activity窗口上设置了一块透明区域。

从总体上描述了SurfaceView的大致实现原理之后,接下来我们就详细分析它的具体实现过程,包括它的绘图表面的创建过程、在宿主窗口上面进行挖洞的过程,以及绘制过程。

requestLayout ,invalidate方法和postInvalidate方法的区别

requestLayout方法会导致View的onMeasure、onLayout、onDraw方法被调用;invalidate方法则只会导致View的onDraw方法被调用

 

七、安卓应用的启动过程

微信的启动流程如下

1.Launcher通知AMS 要启动微信了,并且告诉AMS要启动的是哪个页面也就是首页是哪个页面

2.AMS收到消息告诉Launcher知道了,并且把要启动的页面记下来

3.Launcher进入Paused状态,告诉AMS,你去找微信吧

上述就是Launcher和AMS的交互过程

4.AMS检查微信是否已经启动了也就是是否在后台运行,如果是在后台运行就直接启动,如果不是,AMS会在新的进程中创建一个ActivityThread对象,并启动其中的main函数。

5.微信启动后告诉AMS,启动好了

6.AMS通过之前的记录找出微信的首页,告诉微信应该启动哪个页面

7.微信按照AMS通知的页面去启动就启动成功了。

AMS告诉Launcher我知道了,那么AMS如何告诉Launcher呢?

具体的流程:

得到的是一个Binder对象,代表Launcher所在的App的进程,mToken实际也是一个Binder对象,代表Launcher所在的Activity通过Instrumentation传给AMS,这样AMS就知道是谁发起的请求。

Binder的通信是平等的,谁发消息谁就是客户端,接收的一方就是服务端,前面已经将Launcher所在的进程传过来了,AMS将其保存为一个ActivityRecord对象,这个对象中有一个ApplicationThreadProxy即Binder的代理对象,AMS通ApplicationTreadProxy发送消息,App通过ApplicationThread来接收这个消息。

Launcher收到消息后,再告诉AMS,好的我知道了,那我走了,ApplicationThread调用ActivityThread的sendMessage方法给Launcher主线程发送一个消息。这个时候AMS去启动一个新的进程,并且创建ActivityThread,指定main函数入口。

启动新进程的时候为进程创建了ActivityThread对象,这个就是UI线程,进入main函数后,创建一个Looper,也就是mainLooper,并且创建Application,所以说Application只是对开发人员来说重要而已。创建好后告诉AMS微信启动好了,AMS就记录了这个APP的登记信息,以后AMS通过这个ActivityThread向APP发送消息。

这个时候AMS根据之前的记录告诉微信应该启动哪个Activity,微信就可以启动了。

来源:https://blog.csdn.net/huangliniqng/article/details/89364064

八、安卓两种虚拟机的区别

Dalvik虚拟机

Dalvik虚拟机( Dalvik Virtual Machine ),是由Dan Bornstein编写的,DVM是Google专门为Android平台开发的虚拟机,它运行在Android运行时库中。需要注意的是DVM并不是一个Java虚拟机(以下简称JVM)

Dalvik虚拟机采用的是JIT(Just-In-Time)编译模式,意思为即时编译,我们知道apk被安装到手机中时,对应目录会有dex或odex和apk文件,apk文件存储的是资源文件,而dex或odex(经过优化后的dex文件内部存储class文件)内部存储class文件,每次运行app时虚拟机会将dex文件解释翻译成机器码,这样才算是本地可执行代码,之后被系统运行。

Dalvik虚拟机负责解释dex文件为机器码,如果我们不做处理的话,每次执行代码,都需要Dalvik将dex代码翻译为微处理器指令,然后交给系统处理,这样效率不高。为了解决这个问题,Google在2.2版本添加了JIT编译器,当App运行时,每当遇到一个新类,JIT编译器就会对这个类进行编译,经过编译后的代码,会被优化成相当精简的原生型指令码(即native code),这样在下次执行到相同逻辑的时候,速度就会更快。

安卓虚拟机ART

Android4.4版本以前是Dalvik虚拟机,4.4版本开始引入ART虚拟机(Android Runtime)。在4.4版本上,两种运行时环境共存,可以相互切换,但是在5.0版本以后,Dalvik虚拟机(简称DVM)则被彻底的丢弃,全部采用ART。

ART(Android Runtime) 是一种执行效率更高且更省电的运行机制,执行的是本地机器码,这些本地机器码是从dex字节码转换而来。ART采用的是AOT(Ahead-Of-Time)编译,应用在第一次安装的时候,字节码就会预先编译成机器码存储在本地。在App运行时,ART模式就较Dalvik模式少了解释字节码的过程,所以App的运行效率会有所提高,占用内存也会相应减少。谷哥在5.0以后的Android版本中默认了ART模式启动,就是希望Android能摆脱卡顿这个毛病。

ART和Dalvik的区别

Dalvik就好像拖拉机打火,而ART则只需要一拧就可以了。

  • Dalvik每次都要编译再运行,ART只会安装时启动编译
  • ART占用空间比Dalvik大(原生代码占用的存储空间更大),就是用“空间换时间”
  • ART减少编译,减少了CPU使用频率,使用明显改善电池续航
  • ART应用启动更快、运行更快、体验更流畅、触感反馈更及时

九、binder原理

十、Bitmap内存计算

长*宽*模式所占字节

ARGB_8888:四个通道即A,R,G,B,其中A指半透明的alpha,RGB是颜色通道,每个通道以八位精度存储;这种方式下每个像素占用四个字节,可以提供最高质量的图片,但是最耗内存
ARGB_4444:通道同上,但是每个通道以四位存储;这种方式下每个像素占用两个字节,该模式存储图片质量差,失真明显,但是耗费内存小且拥有Alpha通道
RGB_565:只有RGB三个通道,R通道以五位精度存储,G通道以六位精度存储,B通道以5位精度存储;这种方式每个像素以两个字节存储;当使用不需要高保真的不透明Bitmap时,此配置可能很有用;为了获得更好的结果,应该应用抖动属性
ALPHA_8:只有A通道,每个像素占用一个字节内存,不过只有透明度,不存储颜色信息

 

 

 

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值