Android-Compass is a learning manual about CS basis,Android basis,Android Architecture,useful open resource projects and some knowledge points of performance optimization.
- MVC
- MVP
- MVVM
- MVC,MVP,MVVM总结可以看这篇文章
- Clean
更适用Android的版本:
- 基础特性:
- 框架独立,如工具一般随时可拆卸替换使用。
- 易测试,业务逻辑可以独立测试,不需要UI,数据等外部细节。
- UI独立,UI修改完全不影响其他业务逻辑。
- 数据独立,切换数据库不影响其他业务逻辑。
- 外部代理独立,业务逻辑完全不依赖外部细节。
- 并不是必须是四层结构,这里知识为了展示原理,只要遵循这些思想即可。
- 从外向内的单向依赖。
- 控制的流程是从外到里再到外的,注意上图右下角。([对于这一点,如果有疑问你可以看这里](https://five.agency/wp-content/uploads/2016/11/Graph-1-2.png)
- Use Cases的出现缓解了Presenter的压力
- 项目够大的情况下,会发现MVP有几个重大缺点
- 新增一个V的状态就可能需要多写几个接口,P层接口会很臃肿
- View的接口强依赖View的具体类型(变更View不方便)
- 项目够大的情况下,会发现MVP有几个重大缺点
- 上图中的Presenter我们可以自行选用MVC,MVP,MVVM。
- 关于UseCase的实践:
- 关于模块,见下图:
- 参考文章,参考视频
- 示范:
- MVP + Clean Architecture
- Use Cases/Interactors in Domain layer,就像这里所提到的一样,包括上面MVP + Clean Architecture,都是一个Clean的简化,由于项目比较小,不足以完整展示Clean架构,但是他们都遵循了Clean架构,我们参考即可。
- 感谢以下作者,译者的付出:
- 基础特性:
- Paging
- Databinding
- A java library for generating .java source files.
- 可以看这篇文章
- 很多库都依赖了javapoet,比如ButterKnife,Arouter等等
- SpanUtils(TextView Rich Text Utils,Useful!)
- ...
Interceptors are a powerful mechanism that can monitor, rewrite, and retry calls. OkHttp uses lists to track interceptors, and interceptors are called in order. 更多关于Okhttp
- 原理:用Java的动态代理,把定义的接口转换成具体的请求,并且得到请求结果。动态代理中,通过反射拿到方法的注解信息,构造Http请求。
- 多个BaseUrl,一个Retrofit实例
- 这里我不想接入上面的库,但是HostSelectionInterceptor.java 会影响全路径的请求,可以在上面的基础上改一下:
- Volley
- Gson
- FastJson
- Fresco
- Fresco Architecture Learning:
- Glide
- Piccaso
- Universal-image-loader
- ExoPlayer
- IjkPlayer
- replace drawable shape,(a lot of drawable .xml will make you crazy)
- Reactive Caching library.
- EncriptSharedPreferences:provides an implementation of SharedPreferences that automatically encrypts/decrypts all keys and values
- Another approach is to just use the normal Dagger APIs and follow guides such as the one here. This may be simpler to understand but comes with the downside of having to write extra boilerplate manually
- The better approach is here for Android.
- common issues - UI线程5秒 - BroadCastRecevier5秒 - Service10秒
- dignose
- Strict Mode - Using StrictMode helps you find accidental I/O operations on the main thread while you’re developing your app. You can use StrictMode at the application or activity level - StrictMode is a developer tool which detects things you might be doing by accident and brings them to your attention so you can fix them.
- 生成.trace文件,进一步分析
- Tips
- View复用
- View Cache Pool
- Layout更小的开销
- ViewStub
- Include
- Merge
- Contractlayout替代RelativeLayout,LinearLayout
- 不要重复设置背景
- 抛弃XML,用代码来写View(可以从telegram项目代码学习)
- 原理
- apply() vs commit()
- MMKV替代SharedPreference
- Writing random int for 1000 times, we get this chart:
- MMKV link(api 16)
- ANDROID JSON
- Gson
- FastJson (最快)
- MSON
- 序列化
- Serializable
- Parcelable
- Seria
- BlockCanary
- 原理
- 原理简述,View绘制的时候,总会调用ViewRootImpl的requestlayout(),会看到绘制消息将通过Handler发送。Looper的loop()会调用handler的dispatchMessage();如果卡顿,一定是发生在dispatchMessage里,我们就在dispatchMessage()执行之后设置监听,如果事件差大于16ms就认为是卡顿。dump堆栈和CPU信息就好。
- 如果BlockCanary日志的信息还是无法分析出原因,建议监听CPU活动情况,比如Profiler的Trace Java Methods,然后可以看Flame Chart,找到和项目代码相关的函数,查看耗时,分析可疑函数即可。
- Linux命令
- 图形化工具
- 实现方式有两个流派,instrument:获取某段时间内所有函数的调用的过程,分析函数调用过程,再进一步分析待优化的点;sample:有选择性或者用采样点方式观察某些函数的调用过程,推进出流程的可疑点,再细化分析;
- instrument:
- Traceview,性能损耗比较大
- Naoscope(Uber),性能损耗比较小
- Sample:
- systrace
- TraceView已经被废弃,从Android Studio3.2开始建议用CPU Profiler来替代。
- Android Deviec Monitor在Android Studio3.1被废弃,在Android Studio3.2被移除.
- Android Studio Profiler(降低开发门槛)
- Sample Java Methods(类似traceview的sample类型)
- Trace Java Methods(类似traceview的instrument类型)
- Trace System Calls(类似systrace)
- Sample C/C++ Calls(类似Simpleperf)
- 以上分析工具都支持Call Chart和Flame Chart
- 卡顿原因很多,但最终都会反应到CPU时间上:用户时间和系统时间,分别是用户应用程序代码执行消耗时间和执行内核态系统调用消耗时间,后者包括I/O,锁等
- Inspect CPU
- 频繁GC(内存抖动)
- 内存抖动(Memory Churn), 即大量的对象被创建又在短时间内马上被释放。
- 瞬间产生大量的对象会严重占用 Young Generation 的内存区域, 当达到阀值, 剩余空间不够的时候, 也会触发 GC。即使每次分配的对象需要占用很少的内存,但是他们叠加在一起会增加 Heap 的压力, 从而触发更多的 GC
- Android Profiler
- Bitmap
- 8888
- 565
- 内存泄露容易出现的场景
- Context泄漏(被某个静态类引用,比如单例);解决:Context可以用ApplicationContext代替,及时释放,解绑,解监听。
- 匿名内部类
- 类似Handler这样具备延时操作的场景(1,静态内部类+弱引用;2.及时取消订阅)
- 无限循环Anime,没有关闭,就会导致Activity内存泄漏
- 在服务(系统服务或者自定义服务)中注册监听器,必须及时取消监听
- Rxjava网络请求(可以配合RxLifecycle,AutoDispose)
- 查看内存使用情况
- adb shell dumpsys meminfo packagename
- https://juejin.im/entry/589542ed2f301e0069054007 https://www.jianshu.com/p/ac00e370f83d
- offical docs
- leakcanary
- 1.使用弱引用监听Acitvity或者Fragmmnt的销毁,也可以自己手动调用API去监控一个View
- 2.如果弱引用没有被消除,5秒后运行GC,如果实例还没被消除就是潜在的泄漏
- 3.当潜在的泄漏数量达到阀值,就dumps Javaheap的引用信息到.hprof文件中,app显示的时候阀值是5,否则是1
- 4.LeakCanary会找到一个实例的引用链,从实例到GCROOT最近的强引用一般是原因,但是还是得看情况分析
- 官方文档
- Each thread costs a minimum of 64k of memory.
- Many system processes and third-party libraries often spin up their own threadpools. If your app can reuse an existing threadpool, this reuse may help performance by reducing contention for memory and processing resources. https://juejin.im/post/5cebc989e51d454f72302482?utm_source=gold_browser_extension#heading-14
- 在 Application 的业务初始化代码加入进程判断,确保只在自己需要的进程初始化
- Fultter
- Rn
- Weex
- WebView
- Js&Native Interaction
- JavaScriptInterface
- js用这样的代码调用native:window.JavaScriptInterface.callHandler...
- 使用@JavaScriptInterface来绑定交互方法
- WebViewJavascriptBridge
- js用这样的代码调用native:window.WebViewJavascriptBridge.callHandler...
- WebViewJavascriptBridge
- WebView性能、体验分析与优化
- JavaScriptInterface
- Local Debug
- Put the js code under main/assets
- load url:"file:///android_asset/yourfilename.html"
- Js&Native Interaction
- links
- 签名校验
- jarsigner -certs -verbose -verify xxx.apk (apk是否已经签名?)
- static variable and single instance failed
- thread syncronized failed
- SharedPreferences is not trusted(MMKV is trusted,it is Tencent open resouce project)
- Application will be crated multiple times.
- 可以去这里下载旧版本
- Mac环境下:
- 打开dmg文件,把AndroidStudio移动Applicaiton下,(正常安装布局,本地已经有As会弹出是否覆盖选项,选择keep both)
- 默认是AndroidStudio 2,可以自行更名
- 我这边选择不导入旧配置,不确定选择旧配置是否会有影响,所查资料也是建议用全新的配置,可以在隐藏文件~Library/Application Support看到新的As版本信息
- Gradle和Plugin对应版本要求
- Groovy
- 命令
- Junit is the most popular and widely-used unit testing framework for java.
- a test method begins with the @Test annotation and contains the code to exercise and verify a single functionality in the component that you want to test.
- if you meet runtimeException--Error: "Method ... not mocked",you should add some configuration,because you run a test that calls an API from the Android SDK that you do not mock.
android {
// ...
testOptions {
unitTests.includeAndroidResources = true
}
}
- 上手robolectric填坑推荐阅读: 浅谈测试之 Robolectric
- 【Chinese Blog About Unit Test】(https://www.jianshu.com/p/aa51a3e007e2)
- dagger2结合单元测试,推荐阅读:android-unit-testing-di-dagger
- Android单元测试(五):网络接口测试
- Auto Pack
- Jenkins
- Chinese Introduction
- 注意点:
- 关联Git仓库的时候要添加证书,方式一,仓库HTTP地址+仓库账号密码;方式二,本地创建jenkins SSH,jenins上配置私钥,仓库里配置共钥。说明
- 一定要在Global Tool Configuration(全局工具配置)里配置Git,Gradle信息,前者不配置,拉不到数据,后者不配置无法构建apk
- You can upload your apk ,and you get a qrcode that someone can scan and download apk for test it.I think Pgyer is better because it can keep more valid upload apk history.
- Pgyer
- Fir
- read proguard code
- proguardgui.sh(android_sdk_path/tools/proguard/bin)
- 利用Retrace功能,结合mapping还原被混淆的代码
- Mac在terminal输入proguardgui.sh既可打开工具
- proguardgui.sh(android_sdk_path/tools/proguard/bin)
- Git
- git commit --amend(修改未push的当前本地commit message)
- SourceTree(A Git UI Client)
- Charles
- Introduce to Charles
- Map(When service don't give data,you can custom data)
- 目的
- 较Java层而言,优化性能,对抗逆向
- 生成so流程
- 定义native方法
- javah生成头文件
- 写原生代码
- Android.mk
- Application.mk
- 生成so,ndk-build或者cmake
- 引用
- 必须写和so中一样的native方法同样的包名,类名,方法名
- 配置gradle中设置ndk modulename
- System.loadLibrary("modulename");
- NDK-Build
- CMake
-
Dalvik虚拟机,是Google等厂商合作开发的Android移动设备平台的核心组成部分之一。它可以支持已转换为.dex(即“Dalvik Executable”)格式的Java应用程序的运行。.dex格式是专为Dalvik设计的一种压缩格式,适合内存和处理器速度有限的系统。Dalvik由Dan Bornstein编写的,名字来源于他的祖先曾经居住过的小渔村达尔维克(Dalvík),位于冰岛埃亚峡湾。
-
大多数虚拟机包括JVM都是一种堆栈机器,而Dalvik虚拟机则是寄存器机。两种架构各有优劣,一般而言,基于堆栈的机器需要更多指令,而基于寄存器的机器指令更长。
从Android 5.0版起,Android Runtime(ART)取代Dalvik成为系统内默认虚拟机
- 是一种在Android操作系统上的运行环境,由Google公司研发,并在2013年作为Android 4.4系统中的一项测试功能正式对外发布,在Android 5.0及后续Android版本中作为正式的运行时库取代了以往的Dalvik虚拟机。ART能够把应用程序的字节码转换为机器码,是Android所使用的一种新的虚拟机。它与Dalvik的主要不同在于:Dalvik采用的是JIT技术,而ART采用Ahead-of-time(AOT)技术。ART同时也改善了性能、垃圾回收(Garbage Collection)、应用程序出错以及性能分析。(From:wiki)
-
字节码(英语:Bytecode)通常指的是已经经过编译,但与特定机器代码无关,需要解释器转译后才能成为机器代码的中间代码。字节码通常不像源码一样可以让人阅读,而是编码后的数值常量、引用、指令等构成的序列。
-
字节码主要为了实现特定软件运行和软件环境、与硬件环境无关。字节码的实现方式是通过编译器和虚拟机。编译器将源码编译成字节码,特定平台上的虚拟机将字节码转译为可以直接运行的指令。字节码的典型应用为Java bytecode。
- 负责进程间通信
- Android中各种服务都注册到Binder中
- 这是一种允许进程间共享内存的机制
- https://blog.csdn.net/singwhatiwanna/article/details/49560409
- https://juejin.im/post/5cc3a7495188252e784498b4
- 最强Android书:架构大剖析
- 《Android开发艺术探索》
- 程序员的自我修养
- 垃圾回收算法手册
- Web性能权威
- Unix 网络编程
- Android插件化开发指南
- OpenGL ES 2 for Android
- 翻译过来就是“钩子”,他的作用是截获进程对某个API的调用,使得执行流程指向我们期望的函数。
- GOT/PL Hook
- GOT Hook
- 微信的Matrix开源库ELF Hook(性能监控)
- 爱奇艺开源的xHook
- Facebook PLT Hook
- GOT Hook
- Trap Hook
- Inline Hook
- 《Android开发高手课》(张绍文)
- 《阿里巴巴 Android 开发手册》(1.0.0)
- 《最强Android书 架构大剖析》
- 《Android开发艺术探索》
- 面试时究竟在问些什么
- Android APP 卡顿问题分析及解决方案
- CS-Notes
- 《Android工程师的“面试指南”》(孙鹏飞)
- Linux环境下进程的CPU占用率
- Android 中高级工程师面试复习大纲
- RFC wiki
- Dalvik wiki