刚哥的《Android开发艺术探索》已经很全面了,建议阅读。
5. Bitmap
Bitmap的内存计算方式?
在已知图片的长和宽的像素的情况下,影响内存大小的因素会有资源文件位置和像素点大小。
像素点大小:
常见的像素点有:
- ARGB_8888:4个字节
- ARGB_4444、ARGB_565:2个字节
资源文件位置:
不同dpi对应存放的文件夹
比如一个一张图片的像素为180*180px
,dpi
(设备独立像素密度)为320,如果它仅仅存放在drawable-hdpi
,则有:
横向像素点 = 180 * 320/240 + 0.5f = 240 px
纵向像素点 = 180 * 320/240 + 0.5f = 240 px
如果
如果它仅仅存放在drawable-xxhdpi
,则有:
横向像素点 = 180 * 320/480 + 0.5f = 120 px
纵向像素点 = 180 * 320/480 + 0.5f = 120 px
所以,对于一张180*180px
的图片,设备dpi为320,资源图片仅仅存在drawable-hdpi
,像素点大小为ARGB_4444
,最后生成的文件内存大小为:
横向像素点 = 180 * 320/240 + 0.5f = 240 px
纵向像素点 = 180 * 320/240 + 0.5f = 240 px
内存大小 = 240 * 240 * 2 = 115200byte 约等于 112.5kb
建议阅读:
Bitmap的高效加载?
Bitmap的高效加载在Glide中也用到了,思路:
- 获取需要的长和宽,一般获取控件的长和宽。
- 设置
BitmapFactory.Options
中的inJustDecodeBounds
为true,可以帮助我们在不加载进内存的方式获得Bitmap
的长和宽。 - 对需要的长和宽和Bitmap的长和宽进行对比,从而获得压缩比例,放入
BitmapFactory.Options
中的inSampleSize
属性。 - 设置
BitmapFactory.Options
中的inJustDecodeBounds
为false,将图片加载进内存,进而设置到控件中。
二、Android进阶
Android进阶中重点考察Android Framework
、性能优化和第三方框架。
1. Binder
Binder的介绍?与其他IPC方式的优缺点?
Binder是Android中特有的IPC方式,引用《Android开发艺术探索》中的话(略有改动):
从IPC角度来说,Binder是Android中的一种跨进程通信方式;Binder还可以理解为虚拟的物理设备,它的设备驱动是/dev/binder;从
Android Framework
来讲,Binder是Service Manager
连接各种Manager
和对应的ManagerService
的桥梁。从面向对象和CS模型来讲,Client
通过Binder和远程的Server
进行通讯。
基于Binder,Android还实现了其他的IPC方式,比如AIDL
、Messenger
和ContentProvider
。
与其他IPC比较:
- 效率高:除了内存共享外,其他IPC都需要进行两次数据拷贝,而因为Binder使用内存映射的关系,仅需要一次数据拷贝。
- 安全性好:接收方可以从数据包中获取发送发的进程Id和用户Id,方便验证发送方的身份,其他IPC想要实验只能够主动存入,但是这有可能在发送的过程中被修改。
Binder的通信过程?Binder的原理?
图片:
其实这个过程也可以从AIDL生成的代码中看出。
原理:
Binder的结构:
Client
:服务的请求方。
Server
:服务的提供方。
Service Manager
:为Server
提供Binder
的注册服务,为Client
提供Binder
的查询服务,Server
、Client
和Service Manage
r的通讯都是通过Binder。
Binder驱动
:负责Binder通信机制的建立,提供一系列底层支持。
从上图中,Binder通信的过程是这样的:
- Server在Service Manager中注册:Server进程在创建的时候,也会创建对应的Binder实体,如果要提供服务给Client,就必须为Binder实体注册一个名字。
- Client通过Service Manager获取服务:Client知道服务中Binder实体的名字后,通过名字从Service Manager获取Binder实体的引用。
- Client使用服务与Server进行通信:Client通过调用Binder实体与Server进行通信。
更详细一点?
Binder通信的实质是利用内存映射,将用户进程的内存地址和内核的内存地址映射为同一块物理地址,也就是说他们使用的同一块物理空间,每次创建Binder的时候大概分配128的空间。数据进行传输的时候,从这个内存空间分配一点,用完了再释放即可。
2. 序列化
Android有哪些序列化方式?
为了解决Android中内存序列化速度过慢的问题,Android使用了Parcelable
。
对比 | Serializable | Parcelable |
---|---|---|
易用性 | 简单 | 不是很简单 |
效率 | 低 | 高 |
场景 | IO、网络和数据库 | 内存中 |
3. Framework
Zygote孕育进程过程?
Activity的启动过程?
建议阅读:
App的启动过程?
介绍一下App进程和System Server进程如何联系:
ActivityThread
:依赖于Ui线程,实际处理与AMS
中交互的工作。ActivityManagerService
:负责Activity
、Service
等的生命周期工作。ApplicationThread
:System Server
进程中ApplicatonThreadProxy
的服务端,帮助System Server
进程跟App进程交流。System Server
:Android核心的进程,掌管着Android系统中各种重要的服务。
具体过程:
- 用户点击App图标,
Lanuacher
进程通过Binder
联系到System Server
进程发起startActivity
。 System Server
通过Socket
联系到Zygote
,fork
出一个新的App进程。- 创建出一个新的App进程以后,
Zygote
启动App进程的ActivityThread#main()
方法。 - 在
ActivtiyThread
中,调用AMS
进行ApplicationThread
的绑定。 AMS
发送创建Application
的消息给ApplicationThread
,进而转交给ActivityThread
中的H
,它是一个Handler
,接着进行Application
的创建工作。AMS
以同样的方式创建Activity
,接着就是大家熟悉的创建Activity
的工作了。
Apk的安装过程?
建议阅读:
Activity启动过程跟Window的关系?
建议阅读:
Activity、Window、ViewRoot和DecorView之间的关系?
建议阅读:
4. Context
关于Context的理解?
建议阅读:
5. 断点续传
多线程断点续传?
基础知识:
- Http基础:在Http请求中,可以加入请求头
Range
,下载指定区间的文件数。 RandomAccessFile
:支持随机访问,可以从指定位置进行数据的读写。
有了这个基础以后,思路就清晰了:
- 通过
HttpUrlConnection
获取文件长度。 - 自己分配好线程进行制定区间的文件数据的下载。
- 获取到数据流以后,使用
RandomAccessFile
进行指定位置的读写。
6. 性能优化
平时做了哪些性能优化?
建议阅读:
7. 第三方库
一定要在熟练使用后再去查看原理。
Glide
Glide考察的频率挺高的,常见的问题有:
- Glide和其他图片加载框架的比较?
- 如何设计一个图片加载框架?
- Glide缓存实现机制?
- Glide如何处理生命周期?
- …
建议阅读:
OkHttp
OkHttp常见知识点:
- 责任链模式
interceptors
和networkInterceptors
的区别?
建议看一遍源码,过程并不复杂。
Retrofit
Retrofit常见问题:
- 设计模式和封层解耦的理念
- 动态代理
建议看一遍源码,过程并不复杂。
RxJava
RxJava难在各种操作符,我们了解一下大致的设计思想即可。
建议寻找一些RxJava的文章。
Android Jetpack(非必须)
我主要阅读了Android Jetpack中以下库的源码:
Lifecycle
:观察者模式,组件生命周期中发送事件。DataBinding
:核心就是利用LiveData或者Observablexxx实现的观察者模式,对16进制的状态位更新,之后根据这个状态位去更新对应的内容。
结语
看到这篇文章的人不知道有多少是和我一样的Android程序员。
35岁,这是我们这个行业普遍的失业高发阶段,这种情况下如果还不提升自己的技能,进阶发展,我想,很可能就是本行业的职业生涯的终点了。
我们要有危机意识,切莫等到一切都成定局时才开始追悔莫及。只要有规划的,有系统地学习,进阶提升自己并不难,给自己多充一点电,你才能走的更远。
千里之行始于足下。这是上小学时,那种一元钱一个的日记本上每一页下面都印刷有的一句话,当时只觉得这句话很短,后来渐渐长大才慢慢明白这句话的真正的含义。
有了学习的想法就赶快行动起来吧,不要被其他的事情牵绊住了前行的脚步。不要等到裁员时才开始担忧,不要等到面试前一晚才开始紧张,不要等到35岁甚至更晚才开始想起来要学习要进阶。
给大家一份系统的Android学习进阶资料,希望这份资料可以给大家提供帮助。
加入社区》https://bbs.csdn.net/forums/4304bb5a486d4c3ab8389e65ecb71ac0
这句话很短,后来渐渐长大才慢慢明白这句话的真正的含义。
有了学习的想法就赶快行动起来吧,不要被其他的事情牵绊住了前行的脚步。不要等到裁员时才开始担忧,不要等到面试前一晚才开始紧张,不要等到35岁甚至更晚才开始想起来要学习要进阶。
给大家一份系统的Android学习进阶资料,希望这份资料可以给大家提供帮助。
[外链图片转存中…(img-o7nRe8yV-1725708295285)]
加入社区》https://bbs.csdn.net/forums/4304bb5a486d4c3ab8389e65ecb71ac0