Android开发知识点汇总【转】 LuminousCL

写在前面——本文将持续更新我在学习Android开发过程中遇到的相关知识点汇总,希望自己可以在不断的反思过程中得到提高,同时也感谢所有人给我提供的帮助。


RecycleView

A flexible view for providing a limited window into a large data set.

学习链接

Android控件 RecyclerView

RecyclerView的回收复用机制

组成

RecyclerView的四大组成是:

  • Layout Manager:Item的布局。
  • Adapter:为Item提供数据。
  • Item Decoration:Item之间的Divider。
  • Item Animator:添加、删除Item动画。

布局管理器

RecyclerView提供了三种布局管理器

  • LinerLayoutManager垂直或者水平列表方式展示Item。
  • GridLayoutManager网格方式展示Item。
  • StaggeredGridLayoutManager瀑布流方式展示Item。

常见API

    canScrollHorizontally();//能否横向滚动
    canScrollVertically();//能否纵向滚动
    scrollToPosition(int position);//滚动到指定位置

    setOrientation(int orientation);//设置滚动的方向
    getOrientation();//获取滚动方向

    findViewByPosition(int position);//获取指定位置的Item View
    findFirstCompletelyVisibleItemPosition();//获取第一个完全可见的Item位置
    findFirstVisibleItemPosition();//获取第一个可见Item的位置
    findLastCompletelyVisibleItemPosition();//获取最后一个完全可见的Item位置
    findLastVisibleItemPosition();//获取最后一个可见Item的位置

缓存机制

离屏的ItemView即被回收至缓存,入屏的ItemView则会优先从缓存中获取。

ListView和RecyclerView缓存机制基本一致:

  1. mActiveViews和mAttachedScrap功能相似,意义在于快速重用屏幕上可见的列表项ItemView,而不需要重新createView和bindView;

  2. mScrapView和mCachedViews + mReyclerViewPool功能相似,意义在于缓存离开屏幕的ItemView,目的是让即将进入屏幕的ItemView重用.

  3. RecyclerView的优势在于

  • mCacheViews的使用,可以做到屏幕外的列表项ItemView进入屏幕内时也无须bindView快速重用;
  • mRecyclerPool可以供多个RecyclerView共同使用,在特定场景下,如viewpaper+多个列表页下有优势。

客观来说,RecyclerView在特定场景下对ListView的缓存机制做了补强和完善。

回收机制

RecyclerView和ListView的回收机制非常相似,但是ListView是以View作为单位进行回收RecyclerView是以ViewHolder作为单位进行回收。 Recycler是RecyclerView回收机制的实现类,他实现了四级缓存:

  • mAttachedScrap: 缓存在屏幕上的ViewHolder。
  • mCachedViews: 缓存屏幕外的ViewHolder,默认为2个。ListView对于屏幕外的缓存都会调用getView()
  • mViewCacheExtensions: 需要用户定制,默认不实现。
  • mRecyclerPool: 缓存池,多个RecyclerView共用。

结论

  1. 在一些场景下,如界面初始化,滑动等,ListView和RecyclerView都能很好地工作,两者并没有很大的差异:
  2. 数据源频繁更新的场景,RecyclerView的优势会非常明显;

进一步来讲,结论是: 列表页展示界面,需要支持动画,或者频繁更新,局部刷新,建议使用RecyclerView,更加强大完善,易扩展;其它情况(如微信卡包列表页)两者都OK,但ListView在使用上会更加方便,快捷。


Retrofit

A type-safe HTTP client for Android and Java.

学习链接

Retrofit解析

Handler之同步屏障机制

组成

Retrofit是由Square公司开发的一个开源的高质量高效率的HTTP库,是一个可以简化我们网络操作的工作的第三方库。它将我们自己开发的底层的代码和细节都封装了起来,有了Retrofit之后我们对于一些请求我们就只需要一行代码或者一个注解。所有的网络通信,其核心任务就只有一个就是: Client端与Server端进行数据和交互操作,所有Retrofit就将底层代码都封装起来,只是暴露除了我们业务中的数据模型和操作方法。下图是Retrofit的配置:

注解详解

1、方法注解:@GET @POST@PUT@DELETE@PATCH@OPTIONS@HTTP

2、标记注解:@FormUrlEncoded@Multipart@Streaming

3、参数注解:@Query@QueryMap@Body@Field@FieldMap@Part@PartMap

4、其它注解:@Path@Header@Headers@Url

结论

Retrofit将REST API抽象成Java接口,使用注解来描述每一个API地址和请求,支持URL参数替换(包括查询参数和路径参数),以及表单编码和多部分请求功能。


Android异步通信

学习链接

Android 异步通信:Handler消息传递机制

Android异步消息处理机制完全解析

定义

Android的异步通信机制就是一套消息传递机制。

作用

在多线程的应用场景中,将工作线程中需更新UI的操作信息 传递到 UI主线程,从而实现 工作线程对UI的更新处理,最终实现异步消息的处理。

为什么要用Handler消息传递机制

多个线程并发更新UI的同时 保证线程安全,具体描述如下:

相关概念

关于 Handler机制中的相关概念如下:

在下面的讲解中,我将直接使用英文名讲解,即 HandlerMessageMessage QueueLooper,希望大家先熟悉相关概念

工作原理解析

下面,我将定性地讲解Handler机制的工作流程

工作流程解析

Handler机制的工作流程主要包括4个步骤:

  1. 异步通信准备
  2. 消息发送
  3. 消息循环
  4. 消息处理

具体如下图:

工作流程图

示意图

特别注意

线程(Thread)、循环器(Looper)、处理者(Handler)之间的对应关系如下:

  • 1个线程(Thread)只能绑定 1个循环器(Looper),但可以有多个处理者(Handler)
  • 1个循环器(Looper) 可绑定多个处理者(Handler)
  • 1个处理者(Handler) 只能绑定1个1个循环器(Looper)

同步屏障

当设置了同步屏障之后,next函数将会忽略所有的同步消息,返回异步消息。换句话说就是,设置了同步屏障之后,Handler只会处理异步消息。再换句话说,同步屏障为Handler消息机制增加了一种简单的优先级机制,异步消息的优先级要高于同步消息。


Android事件分发机制

学习链接

Android事件分发机制 详解攻略,您值得拥有

Activity的事件分发机制

ViewGroup事件的分发机制

View事件的分发机制


自定义View

学习链接

Android自定义View全解

自定义View基础 - 最易懂的自定义View原理系列(1)

自定义View Measure过程 - 最易懂的自定义View原理系列(2)

自定义View Layout过程 - 最易懂的自定义View原理系列(3)

自定义View Draw过程- 最易懂的自定义View原理系列(4)

目录大纲

分类

类型定义
自定义组合控件多个空间组合为一个新的控件,方便多处复用
继承系统View控件继承自TextView等系统控件,在系统控件的基础功能上进行扩展
继承View不复用系统控件逻辑,继承View进行功能定义
继承系统ViewGroup继承自LinearLayout等系统控件,在系统控件的基础功能上进行扩展
继承ViewViewGroup不复用系统控件逻辑,继承ViewGroup进行功能定义

1.自定义View基础

2.自定义View Measure过程

3.自定义View Layout过程

4.自定义View Draw过程


Binder

学习链接

Android跨进程通信:图文详解 Binder机制 原理

Binder的定义

  • 中文即 粘合剂,意思为粘合了两个不同的进程
  • 网上有很多对Binder的定义,但都说不清楚:Binder是跨进程通信方式、它实现了IBinder接口,是连接 ServiceManager的桥梁blabla,估计大家都看晕了,没法很好的理解
  • 我认为:对于Binder的定义,在不同场景下其定义不同

在本文的讲解中,按照 大角度 -> 小角度 去分析Binder,即:

  • 先从 机制、模型的角度 去分析 整个Binder跨进程通信机制的模型

其中,会详细分析模型组成中的 Binder驱动

  • 再 从源码实现角度,分析 BinderAndroid中的具体实现

从而全方位地介绍 Binder,希望你们会喜欢。

跨进程通信机制 原理

进程空间划分

  • 一个进程空间分为 用户空间 & 内核空间(Kernel),即把进程内 用户 & 内核 隔离开来
  • 二者区别:
    1. 进程间,用户空间的数据不可共享,所以用户空间 = 不可共享空间
    2. 进程间,内核空间的数据可共享,所以内核空间 = 可共享空间

所有进程共用1个内核空间

  • 进程内 用户空间 & 内核空间 进行交互 需通过 系统调用,主要通过函数:
  1. copy_from_user():将用户空间的数据拷贝到内核空间
  2. copy_to_user():将内核空间的数据拷贝到用户空间

进程隔离 & 跨进程通信(IPC )

  • 进程隔离 为了保证 安全性 & 独立性,一个进程 不能直接操作或者访问另一个进程,即Android的进程是相互独立、隔离的
  • 跨进程通信( IPC ) 即进程间需进行数据交互、通信
  • 跨进程通信的基本原理

a. 而Binder的作用则是:连接 两个进程,实现了mmap()系统调用,主要负责 创建数据接收的缓存空间 & 管理数据接收缓存 b. 传统的跨进程通信需拷贝数据2次,但Binder机制只需1次,主要是使用到了内存映射,具体下面会详细说明

Binder跨进程通信机制 模型

模型原理图

Binder 跨进程通信机制 模型 基于 Client - Server 模式:

模型组成角色说明

梳理Binder的核心原理

模型原理步骤说明

额外说明

说明1

Client进程、Server进程 & Service Manager 进程之间的交互 都必须通过Binder驱动(使用 openioctl文件操作函数),而非直接交互

原因:

  1. Client进程、Server进程 & Service Manager进程属于进程空间的用户空间,不可进行进程间交互
  2. Binder驱动 属于 进程空间的 内核空间,可进行进程间 & 进程内交互

所以,原理图可表示为以下:

虚线表示并非直接交互

说明2

Binder驱动 & Service Manager进程 属于 Android基础架构(即系统已经实现好了),而Client 进程 和 Server 进程 属于Android应用层(需要开发者自己实现)

所以,在进行跨进程通信时,开发者只需自定义Client & Server 进程 并 显式使用上述3个步骤,最终借助 Android的基本架构功能就可完成进程间通信

说明3

Binder请求的线程管理

  • Server进程会创建很多线程来处理Binder请求
  • Binder模型的线程管理 采用Binder驱动的线程池,并由Binder驱动自身进行管理

而不是由Server进程来管理的

  • 一个进程的Binder线程数默认最大是16,超过的请求会被阻塞等待空闲的Binder线程。

所以,在进程间通信时处理并发问题时,如使用ContentProvider时,它的CRUD(创建、检索、更新和删除)方法只能同时有16个线程同时工作


  • 至此,我相信大家对Binder 跨进程通信机制 模型 已经有了一个非常清晰的定性认识
  • 下面,我将通过一个实例,分析Binder跨进程通信机制 模型在 Android中的具体代码实现方式

即分析 上述步骤在Android中具体是用代码如何实现的

Binder机制 在Android中的具体实现原理

  • Binder机制在 Android中的实现主要依靠 Binder类,其实现了IBinder 接口

下面会详细说明

  • 实例说明:Client进程 需要调用 Server进程的加法函数(将整数a和b相加)

即:

  1. Client进程 需要传两个整数给 Server进程
  2. Server进程 需要把相加后的结果 返回给Client进程
  • 具体步骤 下面,我会根据Binder 跨进程通信机制 模型的步骤进行分析

步骤1:注册服务

  • 过程描述 Server进程 通过Binder驱动 向 Service Manager进程 注册服务
  • 代码实现 Server进程 创建 一个 Binder 对象
  1. Binder 实体是 Server进程 在 Binder 驱动中的存在形式
  2. 该对象保存 ServerServiceManager 的信息(保存在内核空间中)
  3. Binder 驱动通过 内核空间的Binder 实体 找到用户空间的Server对象

注册服务后,Binder驱动持有 Server进程创建的Binder实体

步骤2:获取服务

  • Client进程 使用 某个 service前(此处是 相加函数),须 通过Binder驱动 向 ServiceManager进程 获取相应的Service信息
  • 具体代码实现过程如下:

此时,Client进程与 Server进程已经建立了连接

步骤3:使用服务

Client进程 根据获取到的 Service信息(Binder代理对象),通过Binder驱动 建立与 该Service所在Server进程通信的链路,并开始使用服务

  • 过程描述
    1. Client进程 将参数(整数a和b)发送到Server进程
    2. Server进程 根据Client进程要求调用 目标方法(即加法函数)
    3. Server进程 将目标方法的结果(即加法后的结果)返回给Client进程

结论

对比 LinuxAndroid基于Linux)上的其他进程通信方式(管道、消息队列、共享内存、 信号量、Socket),Binder 机制的优点有:


Picasso

学习链接

图片加载框架-Picasso最详细的使用指南

Picasso是Android开发中的经典图片加载框架,可以实现如下功能:

  • 处理Adapter 中ImageView的回收和取消下载。
  • 使用最小的内存 来做复杂的图片变换。比如高斯模糊,圆角、圆形等处理。
  • 自动帮我们缓存图片。内存和磁盘缓存。