目录一、Java相关二、Android重要知识模块1.Android基础2.网络3.数据库SharedPreferences三、架构设计和设计模式1.常用框架2.Jetpack3.注解与事件总线框架注解与依赖注入事件3.1RxJava3.2 协程特点用法3.3 RxJava 和协程优缺点4.设计模式四、性能优化五、模块化、组件化、插件化、热修复区别六、JNI1.JNI注册方式2.C调用JAVA3.System.loadLibrary原理七、开发相关问题1. 系统开发相关2.开发遇到的问题八、调试技巧一、Java相关Java基础知识总结数据结构与算法总结二、Android重要知识模块1.Android基础Android基础知识总结Android Framework知识总结Android重要系统应用模块Android 架构Android 各版本特性2.网络Android网络开发学习总结3.数据库sqlite升级涉及表和字段。表和字段的新增与删除能直接修改字段不支持直接修改需要通过中间文件做转换。数据库框架对比和源码分析如LiteOrm、GreenDao、Realm等。数据库的优化a.使用索引b.语句的拼接使用StringBuilder代替Stringc.查询时返回更少的结果集及更少的字段;d.少用cursor.getColumnIndex;e.异步线程;数据库数据迁移问题创建临时表做中转。如何导入外部数据库1. 把原数据库包括在项目源码的 res/raw 目录下2.在进入应用时若data/data下没有数据库则用写文件的方式把数据库拷入若已有则直接打开。SharedPreferencessharepreferences 是线程安全的底层SharedPreferencesImpl用synchronized来保证同步。但不是进程安全的可通过ContentProvider 实现多进程共同访问。不支持跨进程MODE_MULTI_PROCESS也没用。跨进程频繁读写可能导致数据损坏或丢失。初始化的时候会读取 sp 文件可能导致后续getXXX()方法阻塞。建议提前异步初始化 SharedPreferences。sp 文件的数据会全部保存在内存中所以不宜存放大数据。edit()方法每次都会新建一个EditorImpl对象。建议一次 edit()多次 putXXX() 。无论是commit()还是apply()针对任何修改都是全量写入。建议针对高频修改的配置项存在子啊单独的 sp 文件。commit()同步保存有返回值。apply()异步保存无返回值。onPause()、onReceive()等时机会等待异步写操作执行完成可能造成卡顿或者 ANR。Android中的SharedPreferences是否支持多进程、多线程三、架构设计和设计模式1.常用框架Android 常用开源框架2.Jetpack一系列开发组件的统称方便快速开发应用。Jetpack学习总结3.注解与事件总线框架注解与依赖注入注解与依赖注入几种注解框架对比Annotations 和 ButterKnife 为编译时注解比XUtils运行时注解效率高。事件RxJava的功能与原理实现: 使用可观察序列组成的一个异步地基于事件的响应式编程框架逻辑简单流式结构。RxJava的作用与平时使用的异步操作来比的优缺点。说说EventBus作用实现方式代替EventBus的方式观察者模式依赖反射订阅后处理。如果一个订阅者需要注册多个事件的时候Rxjava需要一个个单独的注册而EventBus则可以实现一个订阅者订阅多个事件和一个事件对应多个订阅者。所以在Rxjava的基础上有了Rxbus来作为事件总线的库。RxBus在订阅者数量很大的情况下性能下降很明显比不过EventBus。RxAndroid 可理解为专供Android平台的RxJava针对平台增加了少量类。3.1RxJava使用可观察序列组成的一个异步地、基于事件的响应式编程框架。// RxJava的链式操作 Observable.create(new ObservableOnSubscribeInteger() { // 1\. 创建被观察者 生产事件 Override public void subscribe(ObservableEmitterInteger emitter) throws Exception { emitter.onNext(1); emitter.onNext(2); emitter.onNext(3); emitter.onComplete(); } }).subscribe(new ObserverInteger() { // 2\. 通过通过订阅subscribe连接观察者和被观察者 // 3\. 创建观察者 定义响应事件的行为 Override public void onSubscribe(Disposable d) { Log.d(TAG, 开始采用subscribe连接); } // 默认最先调用复写的 onSubscribe Override public void onNext(Integer value) { Log.d(TAG, 对Next事件 value 作出响应 ); } Override public void onError(Throwable e) { Log.d(TAG, 对Error事件作出响应); } Override public void onComplete() { Log.d(TAG, 对Complete事件作出响应); } }); } } 注整体方法调用顺序观察者.onSubscribe 被观察者.subscribe 观察者.onNext观察者.onComplete()3.2 协程Android 协程详解,kotlin协程是一种并发设计模式可以用来在Android上简化异步执行的代码。有助于管理长时间运行的任务。可实现类似RxJava效果。特点轻量可以在单线程上运行多个协程。内存泄露少内置取消操作支持jetpack缺点本质是单线程的无法利用多核资源无法避免阻塞虽然协程可以异步处理I/O操作但对于一些需要长时间运行的任务如计算、网络请求等仍然可能导致整个程序阻塞。难以调试由于协程的执行流程比较复杂调试起来相对困难。用法kotlin协程3.3 RxJava 和协程优缺点协程简洁的语法Kotlin协程的语法简洁明了易于学习和使用。高性能由于协程在单线程上运行避免了线程创建和管理的开销提高了执行效率。方便的取消和恢复协程支持取消和恢复这使得在网络请求中处理异常情况变得简单。在使用Kotlin协程进行网络请求时可以考虑使用如Coroutines Retrofit或Coroutines OkHttp等组合它们提供了方便的API来处理异步请求。RxJavaRxJava是ReactiveX在Java平台上的实现它提供了一种基于观察者模式的异步编程模型。通过使用可观察序列Observables和操作符OperatorsRxJava能够以声明式方式处理异步数据流。RxJava的主要优点包括声明式编程RxJava使用声明式语法使得异步操作和数据流的处理更加直观。丰富的操作符RxJava提供了大量操作符可以组合和变换数据流以满足复杂的需求。社区支持由于RxJava在Java社区中的广泛应用有大量的资源和文档可供参考。在使用RxJava进行网络请求时通常会与Retrofit或OkHttp等库结合使用。通过将网络请求封装为Observable或Flowable可以轻松地处理异步数据流。协程适用于处理高并发的IO密集型应用场景尤其在需要大量并发连接的情况下具有优势。不宜用于对于计算密集型的应用场景或者需要利用多核资源的情况。4.设计模式设计模式学习总结四、性能优化Android性能优化学习总结如何对Android 应用进行性能分析以及优化?分类性能问题布局与绘制启动速度 apk启动耗时am start -W 中的waittime内存问题内存泄漏内存浪费。 查看内存使用情况耗电问题网络优化存储优化apk大小稳定性优化检测工具Lint代码检查GPU过度绘制选项查看过渡绘制ddms 和 traceView性能优化如何分析systraceJava多线程引发的性能问题怎么解决利用线程池解决频繁创建与销毁问题减少无意义的同步与伪共享启动页白屏及黑屏解决 设置窗口背景颜色为透明在布局未加载出来时显示当前应用背景。App启动与发布后崩溃异常捕捉在Application 启动时初始化Thread.UncaughtExceptionHandler 类用其去捕捉异常不能捕获native层。native层使用sigaction捕捉异常信号或使用Bugly、google-breakpad等第三方工具。 参考crash log收集总结现在下载速度很慢,试从网络协议的角度分析原因,并优化。 网络拥塞控制ARPDNS解析缓存……五、模块化、组件化、插件化、热修复区别模块化、组件化、插件化、热修复区别热修复目的是为了解决线上的bug或者小功能的更新做到不用为了解决小bug或者小功能而频繁发布版本。核心技术分三类代码修复、资源修复和动态链接库修复。每个核心技术有不同的方案每种方案又有不同的实现。代码修复主要有三个方案底层替换直接在Native层修改原有类不需要重新加载类。阿里系为主。、类加载(基于Dex分包方案主要有是Google官方方案、Dex自动拆包和动态加载方案。不能即时生效。)、Instant Run。资源修复替换系统AssetManger加入patch的资源动态链接库修复先加载patch所在的so;插件化原理分析主要涉及类加载和资源加载。插件化目的是为了解耦业务模块将一个应用里面不同的业务模块都做成一个apk。可并行开发动态加载。模块化实现分模块开发解耦。项目组件化的理解一种开发模式把每个模块使用到的共同的功能抽取出来做成一个Lib去共同依赖每个业务模块互不依赖、互相解耦在开发的时候可以安排不同的开发人员去开发不同的模块开发完毕以后单模块测试最后整合到一起总体测试上线。对于应用更新这块是如何做的(解答灰度强制更新分区域更新)六、JNI1.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},2.C调用JAVAjni如何调用java层代码 C/C调用JAVA获取字节码对象通过字节码对象找到方法对象通过字节码文件创建object对象通过对象调用方法。3.System.loadLibrary原理Runtime.loadLibrary0 先用findLibrary去查找so是否存在然后调用nativeLoad去加载库。nativeLoad 方法参考System.loadLibrary 加载 .so 原理七、开发相关问题1. 系统开发相关Android5种签名类型 :platform、media, shared, testkey/releasekeyApp 是如何沙箱化为什么要这么做 设置UID底层是基于Linux内核的权限机制。权限管理系统底层的权限是如何进行 grant 的 参考 Android权限之底层实现概览内存对象的循环引用及避免内存回收机制的可达性算法。使用弱指针程序中手动释放。系统启动流程是什么init--Zygote进程 – SystemServer进程 – 各种系统服务 – 应用进程一个应用程序安装到手机上时发生了什么Android为每个应用程序分配的内存大小是多少dalvik.vm.heapstartsize8m ----起始分配内存 dalvik.vm.heapgrowthlimit192m ---- 一般情况app申请的最大内存 dalvik.vm.heapsize512mAndroid中进程内存的分配能不能自己分配定额内存进程保活的方式Android进程分类前台可视服务后台空进程。如何保证一个后台服务不被杀死相同问题如何保证service在后台不被kill比较省电的方式是什么什么是协程可看做是轻量级的线程一个线程内能包含多个协程。协程是串行执行的由用户自己控制调度。App中唤醒其他进程的实现方式通过intent的不同用法参考 App相互唤醒的几种方式2.开发遇到的问题工作历史问题技术记录低版本SDK如何实现高版本api用SuppressLint 和 TargetApi 后加入版本判断。为什么不能在子线程更新UI 在更新UI时都会调用 ViewRootImpl 中的 checkThread()方法来判断当前线程是否是主线程若不是就会抛异常。在onCreate方法中可以在子线程中更新UI因为此时ViewRootImpl还没有创建无法做判断。ViewRootImpl是在handleResumeActivity方法中的makeVisible里面创建的。有什么解决方法可以避免OOMOom 是否可以try catch为什么 可以但不应该这样做。怎么去除重复代码 抽象基类布局文件style等。八、调试技巧pm, dumpsys 等相关命令编译命令trace, systrace 等bugreportdebuggerdgdbaddline调试经验总结