设计模式:https://www.jianshu.com/p/35f76e87ac45
java基础:https://xiaozhuanlan.com/topic/7548023169
jvm:
创建对象:https://blog.csdn.net/xiha_zhu/article/details/83614985
jvm面试:https://blog.csdn.net/HarderXin/article/details/104066411
GC回收:https://juejin.cn/post/6844903889850875917#heading-14
- 可达性分析算法
GC Root开始往下搜索,搜索所走过的对象称为引用链,如果一个对象到GCroot没有一个对象关联,则这个对象会被GC回收
GC Root:不会被GC管理的对象,方法区、栈、本地方法区不会进行GC回收
GCRoot:
(JVM栈(栈帧数据中的本地变量表)中引用的对象。方法区中类静态属性引用的对象。
方法区中常量引用的对象。Native 方法栈中JNI引用的对象)。
HashMap:https://cloud.tencent.com/developer/article/1629452
面试题:https://my.oschina.net/u/4584159/blog/4374322
面试题(2的幂)https://www.cnblogs.com/java1024/p/13488714.html
==、hashcode联系:https://www.jianshu.com/p/c7c0828c1de6
String、StringBuffer区别:https://www.jianshu.com/p/2c9a23c8ff0c
http,https/tcp,udp:https://www.jianshu.com/p/e974e6dfa293
https://cloud.tencent.com/developer/article/1572109
线程及进程,安卓中多进程的使用及优劣势分析
java线程池:https://blog.csdn.net/evilcry2012/article/details/79657477
安卓多线程:https://cloud.tencent.com/developer/article/1446299
安卓多进程:
https://chchaooo.github.io/2019/01/19/Android%E5%A4%9A%E8%BF%9B%E7%A8%8B%E9%80%9A%E4%BF%A1/
java理解
反射:https://blog.csdn.net/weixin_43647393/article/details/103301969
注解:https://www.jianshu.com/p/d263fd7aaf96
hook:
整个Hook过程简要总结如下:
寻找Hook点,原则是静态变量或者单例对象,尽量Hook pulic的对象和方法,非public不保证>>每个版本都一样,需要适配。
选择合适的代理方式
如果是接口可以用动态代理; 因为动态代理只用于接口编程
如果是类可以手动写代理,或者直接继承重写函数,也可以使用cglib
偷梁换柱——用代理对象替换原始对象,往往使用反射***
代理
静态代理:编译时期就已经存在,一般首先需要定义接口,而被代理的对象和代理对象一起实现相同的接口。
动态代理:动态代理可以在运行时动态创建一个类,实现一个或多个接口,可以在不修改原有类的基础上动态为通过该类获取的对象添加方法、修改行为。
https://blog.csdn.net/mcryeasy/article/details/83689396?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.control&dist_request_id=1328665.7062.16159520679702053&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.control
Binder序列化:https://blog.csdn.net/weixin_47933729/article/details/112349766?spm=1001.2014.3001.5501
面试题:接口和抽象类的区别?
接口(interface)和抽象类(abstract class)是支持抽象类定义的两种机制。
接口是公开的,不能有私有的方法或变量,接口中的所有方法都没有方法体,通过关键字interface实现。
抽象类是可以有私有方法或私有变量的,通过把类或者类中的方法声明为abstract来表示一个类是抽象类,被声明为抽象的方法不能包含方法体。子类实现方法必须含有相同的或者更低的访问级别(public->protected->private)。抽象类的子类为父类中所有抽象方法的具体实现,否则也是抽象类。
接口可以被看作是抽象类的变体,接口中所有的方法都是抽象的,可以通过接口来间接的实现多重继承。接口中的成员变量都是static final类型,由于抽象类可以包含部分方法的实现,所以,在一些场合下抽象类比接口更有优势。
相同点:(1)都不能被实例化 (2)接口的实现类或抽象类的子类都只有实现了接口或抽象类中的方法后才能实例化。
不同点:
- (1)接口只有定义,不能有方法的实现,java 1.8中可以定义default方法体,而抽象类可以有定义与实现,方法可在抽象类中实现。
- (2)实现接口的关键字为implements,继承抽象类的关键字为extends。一个类可以实现多个接口,但一个类只能继承一个抽象类。所以,使用接口可以间接地实现多重继承。
- (3)接口强调特定功能的实现,而抽象类强调所属关系。
- (4)接口成员变量默认为public static final,必须赋初值,不能被修改;其所有的成员方法都是public、abstract的。抽象类中成员变量默认default,可在子类中被重新定义,也可被重新赋值;抽象方法被abstract修饰,不能被private、static、synchronized和native等修饰,必须以分号结尾,不带花括号。
- (5)接口被用于常用的功能,便于日后维护和添加删除,而抽象类更倾向于充当公共类的角色,不适用于日后重新对立面的代码修改。功能需要累积时用抽象类,不需要累积时用接口。
----------------------------- Android -----------------------------------
安卓源码解析:https://www.kancloud.cn/digest/androidframeworks/127779
activity和fragment:https://cloud.tencent.com/developer/article/1618374
书籍翻页效果: https://www.jianshu.com/p/d02362fbd9f2
ANR及Crash:https://juejin.cn/post/6844903972587716621#heading-5
Native crash:https://cloud.tencent.com/developer/article/1192001
Android优化:
应用启动优化:https://androidperformance.com/2019/11/18/Android-App-Lunch-Optimize/#App-%E4%BC%98%E5%8C%96
内存优化:https://blog.csdn.net/carson_ho/article/details/79549417
动态化方案:
简介:https://tech.meituan.com/2019/09/19/litho-practice-in-dynamic-program-mtflexbox.html
Litho:https://mp.weixin.qq.com/s?__biz=MjM5NjQ5MTI5OA==&mid=2651750430&idx=2&sn=89c8c1212f4b6a24694028ec3188aa09&from=timeline
Android设计模式:
各模式简介:https://www.kancloud.cn/s1657292627/android_ios/622850
MVP+Clean:MVP 之 View 和 Presenter 层作为 Clean 架构的 Presentations Layer, 新增 Domain Layer 处理所有的业务逻辑。MVP 中的 Model 层功能被弱化,作为 Data Layer 对外只提供接口,不再有业务逻辑。 一般来说每一层都有独立的数据模型
https://blog.csdn.net/Kennethdroid/article/details/90178944?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_baidulandingword-13&spm=1001.2101.3001.4242
Android消息机制
一个线程一个Loop,怎么保证?
Thread里存在一个变量threadLocals —> threadLocals=new ThreadLocalMap —>>ThreadLocalMap里面存的是Entry,key存的是ThreadLocal,value即Loop
Loop.prepare()方法中,mThreadLocal.get()!=null—>抛出异常。
Handler面试:
面试题(IdleHandler):https://zhuanlan.zhihu.com/p/356439052
进阶:https://blog.csdn.net/xk7298/article/details/104157542
Threadlocal详解:https://blog.csdn.net/dfskhgalshgkajghljgh/article/details/110187653?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_baidulandingword-6&spm=1001.2101.3001.4242
虚拟机:https://www.jianshu.com/p/4bc97c554884
安卓插件化:https://juejin.cn/post/6844903965679681549#heading-20
dex分包:http://yunlaiwu.github.io/blog/2016/06/15/Dex/
安卓打包编译流程:
- aapt将资源文件打包生成R.java及Resource.arsc
- aidl工具将aidl文件编译成.java文件
- R.java加工程源码加aidl.java通过javac编译生成.class文件
- 源码.class文件和第三方jar或者library通过dx工具打包成dex文件(对 .class 文件进行翻译、重构、解释、压缩)
dexopt对dex文件进行Verification和optimization的操作,其对dex文件的优化结果变成了odex文件,优化内容:
a.对于虚方法的调用,把方法索引修改成vtable索引
b. 把field的get/put修改成字节偏移量。把boolean/byte/char/short等类型的变量
c. 把一些大量使用的简单方法进行inline,减少方法调用的开销
d. 删除空方法
e.加入一些计算好的数据。比如,VM需要一个hash table来查找类名字。- apkbuilder工具会将所有没有编译的资源、.arsc资源、.dex文件打包到一个完成apk文件中
- jarsigner工具会对未签名的apk验证签名。得到一个签名后的apk(signed.apk)
- zipAlign工具对6中的signed.apk进行对齐处理
网络请求:
okhttp:https://blog.csdn.net/u012881042/article/details/79759203
retofit: https://juejin.cn/post/6844903799350362119
网络优化: https://zhuanlan.zhihu.com/p/162429374
Glide:https://juejin.cn/post/6844903986412126216#heading-2
性能优化:https://blog.csdn.net/carson_ho/article/details/79549417
----------------------------- 自己梳理 -----------------------------------
一. App/Activity启动流程
1. 系统启动流程
系统启动:BootLoader拉起linux内核->加载驱动->加载系统OS->init进程开启(init.rc脚本)->zygote进程(作用:孵化进程)->System server进程
zygote进程启动:
init()进程启动完成->解析init.zygote.rc脚本->创建zygote进程->app_main.cpp main()
System server进程(80多个服务)
app_main.cpp main()->安卓运行时环境、启动虚拟机->registerZygoteSocket->开启system server进程->开启loop-
AMS启动:
system server进程的main()->run()->startBootStrapService()、startCoreService()、startOtherService()startBootStrapService()中启动AMS
SystemServiceManager: AMS PMS......
service_manager:管理binder服务
startBootStrapService:
2. startActivity启动流程
跨进程: https://www.cnblogs.com/andy-songwei/p/10256379.html
- 跨进程通信Binder IPC
Binder:https://blog.csdn.net/AndroidStudyDay/article/details/93749470
- 性能:mmap()内存映射,copy一次数据,而socket、管道都是两次;共享内存一次不需要。
- 稳定性:Binder采用C/S架构
- 安全:Linux IPC接收方无法得得到对方进程可靠的UID/PID,无法鉴别对方身份,完全由上层协议确保
AIDL以及序列化:https://blog.csdn.net/weixin_47933729/article/details/112349766?spm=1001.2014.3001.5501
- activity启动流程
instrumentation.execStartActivity->Binder b=ServiceManager.getService()获取到binder服务、IActivityManager.stub.asInterface(b)得到AMS的代理类->AMS.startActivity
AMS.startActivity()->AMS.startActivityAsUser(IApplicationThread caller...):caller用于AMS给app回传
——>ActivityStarter.startActivityMyWait():获取启动意图及启动Activity信息。
——>ActivityStarter.startActivityUnchecked()
——>ActivityStackSupervisor.resumeTopActivityLocked
——>ActivityStackSupervisor.startSpecificActivityLocked()
ProcessRecord...判断应用进程是否存在,不存在,请求zygote fork应用进程。startProcessLocked,请求zygote fork应用进程。
存在,ActivityThread.main(),loop循环,attach,然后IActivityManager.attachApplication, 到AMS.
——>ActivityStackSupervisor.realStartActivityLocked()app.thread.scheduleLaunchActivity(IApplicatiponThread) ,他的实现类是ApplicationThread->ApplicationThread.scheduleLaunchActivity->Handler中处理handleLaunchActivity->performLaunchActivity
performLaunchActivity的主要流程:
- 从ActivityClientRecord中获取待启动Activity的组件信息。
- 通过Instrumentation的newActivity方法使用类加载器去创建Activity对象。
- 通过LoadApk的makeApplication方法来尝试创建Application对象。
- 创建ComtextImpl对象并通过Activity的attach方法来完成一些重要数据的初始化。
- 调用Activity的onCreate方法
3. AMS中的代理模式
ActivityManager的代理模式: https://www.cnblogs.com/mingfeng002/p/10650364.html
三.View绘制及View分发
window相关:https://cloud.tencent.com/developer/article/1601350
view绘制:
简述:
一个 Activity 包含一个Window,Window是一个抽象基类,是 Activity 和整个 View 系统交互的接口,只有一个实现子类PhoneWindow,提供了一系列窗口的方法,比如设置背景,标题等。一个PhoneWindow 对应一个DecorView 跟 一个 ViewRootImpl,DecorView 是ViewTree 里面的顶层布局,是继承于FrameLayout,包含两个子View,一个id=statusBarBackground 的 View 和 LineaLayout,LineaLayout 里面包含 title 跟content,title就是平时用的TitleBar或者ActionBar, content也是FrameLayout,activity通过 setContent()加载布局的时候加载到这个View上。ViewRootImpl就是建立 DecorView 和 Window 之间的联系
viewRootImpl绘制流程详解
ViewRoot对应ViewRootImpl类,它是连接WMS和DecorView的纽带,但它却并不属于View树的一份子,并不是View的子类也不是View的父类,但它实现了ViewParent接口,所以可以作为名义上的View的父视图。
WindowManager.addView()内部实际是由WindowManagerGlobal完成的,WindowManagerGlobal中有三个列表,一个是保存View的mViews列表,一个是保存ViewRootImpl的mRoots列表,一个是保存WindowManager.LayoutParams的mParams列表,WindowManager每一次addView()都会创建一个对应的ViewRootImpl,在调用ViewRoot.setView后将decorView交给ViewRootImpl。ViewRootImpl中调用performTraversals方法,然后便开始测量布局绘画了,界面才得以显示出来,这就是View的绘制流程起点。
- viewRootImpl会调用performTraversals(),其内部会调用performMeasure(),performLayout,performDraw() 方法
- performMeasure()会调用最外层的ViewGroup的measure()--->onMeasure() ---->ViewGroup的onMeasure() 方法是抽象方法,但其提供了measeureChilden()方法,这个会遍历子View 然后循环调用measureChilden() ,这个方法中会调用getChildMeasureSpec() + 父View的MeasureSpec + 子View的LayoutParam 一起获取到本身View的MeasueSpec,然后调用子View的measure()到view的onMeasure()--->setMeasuredDimension(getDefaultSize(),getDefaultSize()) 默认返回measureSpec的测量数值 ,所以继承View 进行自定义的wrap_content 需要重写
- performLayout() 会调用最外层的ViewGroup的layou(l,t,r,b) ,本身View在其中使用setFrame(),设置本View的四个顶点位置,在onLayout(抽象方法)中确定子View的位置 ,比如LinearLayout 会遍历子View ,循环调用 setChildFrame--->子View的layout方法
- performDraw()会调用最外层的ViewGroup的draw(),其中会先后调用background.draw () 绘制背景,onDraw 方法 绘制自己本身View ---> 调用dispatchDraw() 进行子View 绘制---->onDrawScrollBars() 绘制装饰
- MeasureSpec 由2位SpecMode(UNSPECIFIED,EXACTILY(对应精确值和match_parent),AT_MOST 对应warp_content) 和30位SpecSize 组成一个int,DecorView的MeasureSpec 是由窗口大小与其LayoutParams决定,其他View 是由父View的MeasureSpec 和本身的View的layoutParams 来决定 ,ViewGroup 中有getChildenMeasureSpec() 来获取子View 的measureSpec
EXACTLY:父容器已经测量出子View的大小。对应是 View 的LayoutParams的match_parent 或者精确数值。
AT_MOST:父容器已经限制子view的大小,View 最终大小不可超过这个值。对应是 View 的LayoutParams的wrap_content
UNSPECIFIED:父容器不对View有任何限制,要多大给多大,这种情况一般用于系统内部,表示一种测量的状态。 - 三种方式获取measure()后的宽高值
a.activity中的onWindowFocusChange() 方法中调用获取
b.view.post(Runnable) 将在run方法中进行获取
c.view.setViewTreeObserbable 监听中进行获取
draw流程
- draw
- drawBackground(canvas): 作用就是绘制 View 的背景。
- onDraw(canvas) :绘制 View 的内容。View 的内容是根据自己需求自己绘制的,所以方法是一个空方法,View的继承类自己复写实现绘制内容。
- dispatchDraw(canvas):遍历子View进行绘制内容。在 View 里面是一个空实现,ViewGroup 里面才会有实现。在自定义 ViewGroup 一般不用复写这个方法,因为它在里面的实现帮我们实现了子 View 的绘制过程,基本满足需求。
- onDrawForeground(canvas):对前景色跟滚动条进行绘制。
- drawDefaultFocusHighlight(canvas):绘制默认焦点高亮
View事件分发机制:
原理:https://www.jianshu.com/p/e99b5e8bd67b
面试题:https://segmentfault.com/a/1190000039254459
RecycleView缓存: https://www.cnblogs.com/jimuzz/p/14040674.html
滑动冲突:https://blog.csdn.net/wk_beicai/article/details/83302739?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.control&dist_request_id=&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.control
view绘制及recyclerView相关: https://blog.csdn.net/harvic880925/article/details/50995268
算法:
二分查找: https://blog.csdn.net/maoyuanming0806/article/details/78176957