目录
目录
Java
Android重要知识模块
网络
数据库
- sqlite升级:涉及表和字段。表和字段的新增与删除能直接修改,字段不支持直接修改,需要通过中间文件做转换。
- 数据库框架对比和源码分析:如LiteOrm、GreenDao、Realm等。
- 数据库的优化:a.使用索引;b.语句的拼接使用StringBuilder代替String;c.查询时返回更少的结果集及更少的字段;d.少用cursor.getColumnIndex;e.异步线程;
- 数据库数据迁移问题:创建临时表做中转。
- 如何导入外部数据库:1. 把原数据库包括在项目源码的 res/raw 目录下,2.在进入应用时,若data/data下没有数据库,则用写文件的方式把数据库拷入,若已有则直接打开。
sharepreferences 是进程同步的吗?有什么方法做到同步?不是,其是单文件的,默认没有考虑同步互斥问题,可通过ContentProvider 实现多进程共同访问。其是线程安全的,里面synchronized来保证同步。
架构设计和设计模式
Android开发常用轮子-2019 包含部分网络框架
Android 快速开发开源框架 2014年
注解与事件总线框架
- RxJava的功能与原理实现: 使用可观察序列组成的一个异步地,基于事件的响应式编程框架,逻辑简单,流式结构。
- RxJava的作用,与平时使用的异步操作来比的优缺点。
- 说说EventBus作用,实现方式,代替EventBus的方式:观察者模式,依赖反射,订阅后处理。
- 如果一个订阅者需要注册多个事件的时候,Rxjava需要一个个单独的注册,而EventBus则可以实现一个订阅者订阅多个事件,和一个事件对应多个订阅者。所以在Rxjava的基础上有了Rxbus来作为事件总线的库。RxBus在订阅者数量很大的情况下性能下降很明显,比不过EventBus。
设计模式
性能优化
- 如何对Android 应用进行性能分析以及优化?
- 分类:
- 性能问题:布局与绘制;启动速度; apk启动耗时:am start -W 中的waittime
- 内存问题:内存泄漏,内存浪费。 查看内存使用情况
- 耗电问题:
- 存储优化:
- apk大小
- 检测工具:Lint代码检查,GPU过度绘制选项查看过渡绘制,
- 分类:
- ddms 和 traceView
- 性能优化如何分析systrace?
- Java多线程引发的性能问题,怎么解决?
- 利用线程池解决频繁创建与销毁问题;
- 减少无意义的同步,与伪共享;
- 启动页白屏及黑屏解决? 设置窗口背景颜色为透明,在布局未加载出来时,显示当前应用背景。
- App启动与发布后崩溃异常捕捉:在Application 启动时初始化Thread.UncaughtExceptionHandler 类,用其去捕捉异常,不能捕获native层。native层使用sigaction捕捉异常信号,或使用Bugly、google-breakpad等第三方工具。 参考crash log收集总结
- 现在下载速度很慢,试从网络协议的角度分析原因,并优化。 网络拥塞控制;ARP;DNS解析;缓存……
模块化与更新
- 热修复:目的是为了解决线上的bug或者小功能的更新,做到不用为了解决小bug或者小功能而频繁发布版本。核心技术分三类:代码修复、资源修复和动态链接库修复。每个核心技术有不同的方案,每种方案又有不同的实现。
- 代码修复:主要有三个方案:底层替换(直接在Native层修改原有类,不需要重新加载类。阿里系为主。)、类加载(基于Dex分包方案,主要有是Google官方方案、Dex自动拆包和动态加载方案。不能即时生效。)、Instant Run。
- 资源修复:替换系统AssetManger,加入patch的资源
- 动态链接库修复:先加载patch所在的so;
- 插件化原理分析:主要涉及类加载和资源加载。插件化目的是为了解耦业务模块,将一个应用里面不同的业务模块都做成一个apk。可并行开发,动态加载。
- 模块化实现:分模块开发,解耦。
- 项目组件化的理解:一种开发模式,把每个模块使用到的共同的功能抽取出来做成一个Lib去共同依赖,每个业务模块互不依赖、互相解耦,在开发的时候可以安排不同的开发人员去开发不同的模块,开发完毕以后单模块测试,最后整合到一起总体测试上线。
- 对于应用更新这块是如何做的?(解答:灰度,强制更新,分区域更新)?
JNI
JNI注册方式
- jni中注册native函数方法: 注册JNI函数的两种方式
- 静态注册:每个class都得用javah生成一个头文件,名字长,首次调用慢。类似 android_com_media_Target_test() ,通过函数命令规则查找响应函数。
- 动态注册:要在jni_onload 中注册。有类似 { "hello", "()Ljava/lang/String;", (void*)native_hello} 对应关系。 {"native_start", "()V", (void *)android_media_AudioTrack_start},
C调用JAVA
- jni如何调用java层代码? C/C++调用JAVA
- 获取字节码对象;
- 通过字节码对象找到方法对象;
- 通过字节码文件创建object对象;
- 通过对象调用方法。
System.loadLibrary原理
Runtime.loadLibrary0 先用findLibrary去查找so是否存在,然后调用nativeLoad去加载库。
nativeLoad 方法参考:System.loadLibrary 加载 .so 原理
系统开发相关
- Android5种签名类型 :platform、media, shared, testkey/releasekey
- App 是如何沙箱化,为什么要这么做? 设置UID,底层是基于Linux内核的权限机制。
- 权限管理系统(底层的权限是如何进行 grant 的)? 参考 Android权限之底层实现概览
- 内存对象的循环引用及避免:内存回收机制的可达性算法。使用弱指针,程序中手动释放。
- 系统启动流程是什么?(init--Zygote进程 –> SystemServer进程 –> 各种系统服务 –> 应用进程)
- 一个应用程序安装到手机上时发生了什么
- Android为每个应用程序分配的内存大小是多少?
dalvik.vm.heapstartsize=8m ----起始分配内存 dalvik.vm.heapgrowthlimit=192m ---- 一般情况app申请的最大内存 dalvik.vm.heapsize=512m
- Android中进程内存的分配,能不能自己分配定额内存?
- 进程保活的方式:Android进程分类?前台,可视,服务,后台,空进程。
- 如何保证一个后台服务不被杀死?(相同问题:如何保证service在后台不被kill?)比较省电的方式是什么?
- 什么是协程?:可看做是轻量级的线程,一个线程内能包含多个协程。协程是串行执行的,由用户自己控制调度。
- App中唤醒其他进程的实现方式:通过intent的不同用法,参考 App相互唤醒的几种方式
开发相关问题
- 工作历史问题技术记录
- 低版本SDK如何实现高版本api:用@SuppressLint 和 @TargetApi 后加入版本判断。
- 为什么不能在子线程更新UI? 在更新UI时都会调用 ViewRootImpl 中的 checkThread()方法来判断当前线程是否是主线程,若不是就会抛异常。在onCreate方法中可以在子线程中更新UI,因为此时ViewRootImpl还没有创建,无法做判断。ViewRootImpl是在handleResumeActivity方法中的makeVisible里面创建的。
- 有什么解决方法可以避免OOM?
- Oom 是否可以try catch?为什么? 可以,但不应该这样做。
- 怎么去除重复代码? 抽象基类,布局文件,style等。