Android 思想

性能优化:

TraceView 优点:
通过埋点的方式精确的调试某个方法。
TraceView 缺点:
目前 DDMS 中的 TraceView 有 bug,find 无法使用。直接用 sdk 的 可以 find。
运行时开销大,整体都会变慢。
直接用 Android Studio 查看 trace 文件的缺点:无法直观地对比不同线程的执行时间。

Profiler

开源库的原理:

事件总线:EventBus,Otto;
图片库:Picasso,Fresco,Glide;
网络库:Volley,Retrofit,OkHttp3;
注解:Butternife;
数据库:GreenDAO;SQLChiper;
解析:Gson,Jackson;
架构:RxJava,DataBinding,Architecture;

动态排版:

阿里的 Tangram 七巧板,
阿里的LuaView我没细看过源码,但其实内部机制和RN&WEEX没啥区别,用的是FlexBox排版,但是选用的是Lua Engine这个脚本引擎。
NinePatchChunk

换肤:

1,本地预埋方式:
— values 目录里面定义 attr
— values 定义多套 stytle
— 控件style属性统一用 ?attr/xxx
— 切换主题,设置 context.setTheme,BaseActivity 里面重启下 Activity;
2,云控动态方式:
— 动态下发apk,利用 AssetManager 反射 addAssetPath 方法得到 am ,再创建 Resources 对象;
— 实现自己的 LayoutInflate.Factory,LayoutInflater设置 Factory;
https://www.jianshu.com/p/c2b1ae56381e

热修复:

1,QQ空间方案:改变 BaseDexClassLoader 中的 dexElements 数组,将我们的 patch.jar 插入到 dexElements 数组的第一个位置;
在打包的时候,我们要阻止类被打上 CLASS_ISPREVERIFIED 标记,通过 APT 编译时注入代码;
2,AndFix:在 Native 层使用指针替换的方式替换bug方法,以达到修复 bug 的目的;
3,Instant Run|Robust:插桩的方式,打包的时候,利用APT编译时注入代码,每个类里面加上代理类(它有本类的所有方法) c h a n g e 变 量 , 每 个 方 法 判 断 change变量,每个方法判断 changechange不为空则走它的方法;修复的时候,利用反射机制把新类赋值给$change,这样就达到目的了;
4,Tinker:得到一个差量的补丁包dex,修复的时候跟老的dex合并成一个新的dex;

插件化:

DroidPlugin:
类加载用DexClassLoader;
资源加载用AssetManager反射addAssetPath方法得到am,再创建 Resources对象;
new DexClassLoader 的时候可以传 libraryPath;
activity注册问题,1,可以通过接口代理;2,hook Activity启动流程;
RePlugin:
就hook了PathClassLoader(Application.mBase.mPackageInfo.mClasslLoader);
核心步骤:
记录:通过PM.startActivity方法来“记录”到要打开的Activity的名字;
寻找坑:通过一系列流程来找到一个可用的坑位(如N1ST1)并记录;
开启坑:通过系统的startActivity来直接打开这个坑位(注意,此处没有做Hook);
拦截:当系统调到我们的HostClassLoader(唯一Hook点)时,我们“拦了一道”,找到此坑位(N1ST1)对应的真正的Activity(XXXActivity);
返回:加载插件并获取这个真正的Activity的Class对象并返回给系统。

组件化:

多个Module,Activity跳转用URI;
基础Common依赖定义接口,其他aar具体实现接口,再有个工厂类利用反射得到具体实现;其他aar都依赖Common层;

版本兼容:

https://blog.csdn.net/miLLlulei/article/details/104943279

事件分发:

从Action_Down开始的,ViewGroup dispatchTouchEvent开始分发,如果 onIntercepte 没有拦截,则会遍历点击范围内的子View,如果某个子View消费了(也就是OnTouchEvent return true了),那么后面的 Action_Move| Action_Up 都会直接给那个View OnTouchEvent处理;如果这时候 ViewGroup onIntercepte return true了,那么会跟那个子View发送一个Action_Cancel的事件,再之后的Action_Move | Action_Up就会给ViewGroup OnTouchEvent处理了;如果所有子View都没有消费Action_Down的事件,那么之后的Action_Move | Action_Up都会是ViewGroup自己OnTouchEvent处理了;
触摸事件的源头:InputManagerService
InputManagerService,创建了一个事件读取线程,还创建了一个事件派发线程。
大体流程:
1,点击屏幕
2,InputManagerService的 Read 线程捕获事件,预处理后发送给 Dispatcher 线程
3,Dispatcher找到目标窗口
4,通过Socket将事件发送到目标窗口
5,APP端被唤醒
6,找到目标窗口处理事件

自定义控件:

1,组合系统控件;
2,继承系统控件,特殊处理;
3,自定义 View:
https://www.jianshu.com/p/56006bc13dcf

多进程:

1,Application 会多次重建;
2,进程间,对象不共享内存;
3,AIDL,ContentProvider;

Intent 6属性:

1,ComponentName
2,Data
3,Extra
4,Action
5,Category
6,Flag

四大组件:

1,Activity
https://www.jianshu.com/p/476087b4c087
Activity启动流程:
ContextImpl -> Instrumentation -> AMS -> ApplicationThread -> ActivityThread -> H.handleMessage
2,Service
https://blog.csdn.net/weixin_39460667/article/details/82770164
Service启动流程:
ContextImpl -> AMS -> 发消息到 ActivityThread,走生命周期
3,BroadcastReceiver
BroadcastReceiver启动流程:
https://www.jianshu.com/p/f348f6d7fe59
ContextImpl -> AMS -> BroadcastQueue
4,ContentProvider
https://blog.csdn.net/qq_34760508/article/details/95314242
ContentProvider启动流程(类似AIDL):
ContextImpl -> ApplicationContentResolver -> ActivityThread <-> AMS -> ContentProviderNative

你可能感兴趣的:(面试,Android)