0%

总结-新

  • 优化:闪屏、极速版、viewStub、IdleHandler加载Webview、classes.dex只保留App启动所需要的代码、避开峰值,滑动时不加载图片。线程优化-采用线程池、不加载大的sp,监控方式:视频录制

  • 内存泄漏,比如 EventBus没有反注册、Activity被静态持有

  • 衡量指标: 快开慢开比:比如2秒快开比,5秒快开比;90% 用户启动时间。冷启动,从3.5秒左右降低到1秒左右,内存从经常性的 380M 左右降低到 330M 的水平,优化前88%左右,93%的收集数据显示1秒以内打开;主要集中在网络超时、网络无连接两种异常,其中网络超时占了40%左右

  • Serializable 的反序列默认是不会执行构造函数的
  • SQLite 默认支持多进程并发操作,它通过文件锁来控制多进程的并发,但是SQLite 的锁粒度并没有非常细,针对的是整个DB文件,简单来说,多进程可以同时获取 SHARED 锁来读取数据,但是只有一个进程可以获取 EXCLUSIVE 锁来写数据库
  • 网络请求: DNS解析(本地或服务查询)、连接(握手、TLS、慢启动、重定向)、发送数据包(延迟、丢包)、接收(IO、解析)、关闭
  • 网络性能监控:360的 ArgusAPM插桩技术、以及 TraceNetTrafficMonitor :使用Aspect 切面功能
  • 软件绘制使用的是 Skia 库,画笔:Skia或者OpenGL;画纸:Surface;画板:Graphic Buffer
  • 硬件绘制与软件绘制最核心的区别是硬件绘制通过GPU完成 Graphic Buffer内容的绘制
  • Surface 对应2个Buffer,一个前台的,一个后台的,Surface与Buffer之间通过 匿名共享内存交换数据的。可以采用 Tracer for OpenGL ES 逐帧分析性能
  • Android的多渠道打包其中的一种思路就是这样,在 apk 尾巴上追加几个字节,来标记apk的渠道,apk启动时,从apk尾巴上读取这个渠道值。不过,后来google发现了这个漏洞,在新版本系统中,系统安装apk时,会检查apk实际大小,二者不相等就会报错安装失败
  • UI渲染用 gfxinfo 监测性能,当然也可以用 Systrace,怎么操作?
  • SharedPreference 缺点:跨进程不安全、加载慢(异步加载,可能主线程会等待)、卡顿(onPause会强制写入磁盘)、Json转义
  • ContentProvider 的原理:通过 Binder 传输匿名共享内存的文件描述符给数据获取方(Client内部有一个 CursorWindow 对象,发送请求时,把这个CursorWindow 类型对象传过去,这个对象暂时为空,Server 收到请求,搜集数据,填充到这个CursorWindow 对象中,Client 读取内部这个CursorWindow 对象,获取数据)。适合传输大量数据,传小数据不一定划算
  • 静态代理就是对于每种情形都编写一个Proxy,在调用的时候,使用真实的target的来调用方法;动态代理就是根据系统提供的Proxy.newProxyInstance,它的原理是通过 Method.invok ,避免创建多个Proxy
  • 动态广播先于静态广播接收到
  • assets目录存放的文件,最终还是通过 getResources 去open打开,所以,资源文件都可以归结到 Resource 里面
  • 资源插件化解决:创建AssertManager对象,调用 addAssertPath 将所有的插件路径都添加进去,之后根据AssetManager对象创建 Resources 和 Theme 对象。 重写 Activity 的 getAsset、getResources 、和 getTheme 方法(第8、15章)。
  • 资源插件化问题解决:修改AAPT以及打包gradle文件,为插件资源指定不同前缀。插件使用宿主的资源,就固定id;宿主通过provider 以 aar形式引入到 插件项目中
  • 动态广播插件化:动态广播,只需要保证宿主APP能加载到动态广播类就行,所以,无序特别处理
  • Service、ContentProvider、广播这些通用方案都是本地站位,因为数量不多
  • ACTION_DOWN事件在哪个控件消费了(return true), 那么ACTION_MOVE和ACTION_UP就会从上往下(通过dispatchTouchEvent)做事件分发往下传,就只会传到这个控件,不会继续往下传,如果ACTION_DOWN事件是在dispatchTouchEvent消费,那么事件到此为止停止传递,如果ACTION_DOWN事件是在onTouchEvent消费的,那么会把ACTION_MOVE或ACTION_UP事件传给该控件的onTouchEvent处理并结束传递。(事件分发机制)
  • getX 是获取事件到屏幕的距离;getRawX 是获取事件距离控件顶边的距离
  • View的滑动方法: layout、LayoutParams、属性动画、ObjectAnimator、offsetLeftAndRight、scrollTo、scrollBy、Scroller(computeScroll)
  • Zygote 启动SystemServer,后者再启动各种服务,比如 AMS、WMS
  • React 只关注MVC框架中的View层,为减少直接操作DOM,它使用虚拟DOM来差异化更新 DOM,实现数据单向流动。而传统的HTML 页面更新元素是全量更新
  • RN 的UI层变化, 就映射到 虚拟DOM,计算出diff后转成json发送给Native生成页面元素。编写的 RN 代码最终会打包成 main.bundle.js 文件供App 加载,此文件可以存在App本地或者服务器上更新。我个人的理解是,生成虚拟DOM之后的.js文件发到Android或者ios中,由本地进行差异对比生成json,本地再根据json更改view。
  • B想从A中获取数据,然后呢,它就mmap 一块内存,这块内存对应到物理内存上,但是Binder驱动在内核空间中也指向一块虚拟内存K,这块内存与B那块内存在物理上是一样的。这时候,只需要A将通过 copy_from_user 将数据复制到 K 中,即完成了数据的一次复制。同步回去博客
  • 直接内存,NIO : 在Native 分配堆外内存,在Java对中通过 DirectBuffer 作为引用
  • GC Root: 虚拟机栈引用、本地方法栈引用、方法区静态、方法区中常量
  • 类加载过程: 加载、校验、准备、解析(将常量池的符号引用搞成直接引用)、初始化、使用、卸载
  • 锁优化:自旋、锁消除、锁粗化、轻量级锁、偏向锁
  • 轻量级锁,使用CAS操作尝试将对象的 MarkWord 改成轻量级锁标志,如果成功,则拥有锁;否则,判断锁是否指向当前线程,如果是,则直接进入。否则,就等待(个人觉得应该是CAS重试)。如果有两个以上线程在争用这个锁,就升级为重量级锁,后面的线程阻塞。
  • 偏向锁:偏向锁在轻量级锁基础上连 CAS 都不做。在对象第一次被线程获取后,把线程id写在 MarkWord 中(这个当然是CAS操作),当另一个线程尝试获取的时候,偏向模式就结束(指的是这个CAS操作不做了),恢复到未锁定或者轻量级锁状态,后续就是轻量级锁规则了
  • 拥塞控制方法: 慢启动、拥塞避免(增速慢,不再翻番)、快速恢复(拥塞窗口减半,再做拥塞避免)
  • TCP慢可能的原因:握手、捎带确认算法、拥塞控制算法
  • 数字签名就是加了密的摘要。证书包含的内容: 证书格式、对象名称、对象的公钥、有效期、颁发者、签名算法等
  • lateinit 主要用于 var 声明的变量,然而它不能用于基本数据类型,如 Int、Long 等,我们需要使用Integet这种包装类作为替代
  • Data class 的特点是: 默认给写了getter、setter、equals、copy(浅拷贝)、toString 等方法
  • Kotlin 中的 Int 类型等同于 int
  • Kotlin 中的 Int? 等同于 Integer !
  • 一般来说,Kotlin 属于 无栈协程,它依靠对协程体本身编译生成的状态机的状态流转实现,变量的保存也是通过闭包语法实现
  • adb shell -》 run as -》 cd /data/data/app_webview,非Root情况下 获取webview的Cookies ,使用 sqlite3打开即可
  • MeasureSpec 的含义是:父View传递给当前 View 的一个建议值。UNSPECIFIED 父不约束子,子View可以取任意尺寸。Exactly(match_parent、具体数值): 父为子指定特定的尺寸,子必须在这个尺寸之内 ;AT_MOST(wrap_content):父为子指定一个最大的尺寸,子要在这里面
  • 当子具体数值时:EXACTLY,大小为数值;当子为 match_parent: 为父容器的mode,父的剩余空间;当子为wrap_content: mode 为 AT_MOST ,不超过父容器
  • 内部拦截手势冲突时,在setOntouchListener 中 disallowParent设置为 true,在合适的时候,再设置为false。
  • 在WebviewClient 的 shouldInterceptRequest ,自行重新组装 WebResourceResponse
  • 安全努力:app签名校验、https防抓包、本地广播、sp加密
  • 自己写AIDL,会生成Stub 接口,在用于数据传递的Service (在主进程)中 自己写 binder实现 Stub 接口,实现其中的方法,在onBind 方法中返回这个 binder 。将数据传给webview: webview.loadUrl(“javascript:”)
  • handler处理流程:首先判断msg.callback 、其次是Handler的mCallback,最后才是交给 Handler 的 handleMessage 处理
  • epoll: 以前是将文件描述符数组发给内核,内核遍历;现在是 内核保存了一份文件描述符,只需要穿进去改动的部分。以前内核轮询来发现是否可以读写,现在是通过异步IO事件唤醒而不是轮询;最后,现在系统是仅将有IO事件的文件描述符返回给用户。
  • ViewRootImpl 的 scheduleTraversals ,会往MessageQueue 中插入同步屏障 msg,之后在Vsync的时候,就会发送异步消息。之后在unscheduleTraversals中移除
  • ANR: 输入5s,广播:前台10,后台60;服务:前台20,后台200;ContentProvider 的publish 超时 10s
  • 内存分配流程: 分配-> GC无soft -> 增长到最大 -> GC 有 soft ,增长大最大 -> OOM
  • 挂堆、标记、放堆、挂起线程、

想让消息提前执行?

可重入的原理

启动模式兼容?无论singleTop还是singleTask,再回到这个Activity时,并不会触发它的onCreate,而是会触发它的onNewIntent(其实这里说的bug我并没有明白,等测试后再说)。为此,我们需要在MockClass2 中,拦截onNewIntent方法,把占位 StubActivity 替换回插件Activity,代码如下:

写个自定义容器,在里面横着放子View,当一行放不下一个View的时候,自动换行

RenderThread?

Binder原理?两种签名方式?

systrace + 函数插桩怎么操作

HardwarLayout、SoftWareLayout

RN布局常用的方法

Android 中 js 桥的原理

谢谢你的鼓励