第三方框架(原理)分析。
Android平台主流开源框架的源码与原理实现- https://github.com/sucese/android-open-framework-analysis
--常用的框架分为下面几类:
1.UI框架和自定义控件;
2.网络请求框架;
3.图片缓存框架;
4.数据存储框架;
5.事件总线框架;
6.插件化和热部署;
分析具体耗时的Trace view;布局复杂度工具Hierarchy View;静态代码检查工具Lint;程序稳定性monkey。AndroidStudio也有Device Monitor,也提供内存监测工具 Heap,可以使用 Heap 监测应用进程使用内存情况。
HierarchyViewer分析UI性能;GPU过度绘制分析UI性能;使用Memory监测及GC打印与Allocation Tracker进行UI卡顿分析;运行DDMS-> Allocation Tracker;使用Traceview和dmtracedump进行分析优化;使用Systrace进行分析优化;使用traces.txt文件进行ANR分析优化。
1.Android Lint工具时AndroidStudio中集成的一个Android代码提示工具,它可以给你的布局、代码提高非常强大的帮助。
2.Memory Monitor工具是Android Studio自带的一个内存监视工具,他可以很好的帮助我们进行内存实时分析。通过点击Android Studio左下角的“Android Profiler”标签,打开Memory Monitor工具
3.TraceView是一个Android下的可视化性能调查工具,它用来分析TraceView日志。通过代码生成精确范围的TraceView日志;通过Android Device Monitor生成TraceView日志
4.MAT(Memory Analyzer Tool)工具是一个分析内存的强力助手。生成HPROF文件
> LeakCanary,MAT
LeakCanay的入口是在application的onCreate()方法中声明的,其实用的就是Application的ActivityLifecycleCallbacks回调接口监听所有activity的onDestory()的,在这个方法进行RefWatcher.watch对这个对象进行监控。
具体是这样做的,封装成带key的弱引用对象,然后GC看弱引用对象有没有回收,没有回收的话就怀疑是泄漏了,需要二次确认。然后生成HPROF文件,分析这个快照文件有没有存在带这个key值的泄漏对象,如果没有,那么没有泄漏,否则找出最短路径,打印给我们,我们就能够找到这个泄漏对象了。
LeakCanary基本工作原理如下:
1.RefWatcher.watch() 创建一个 KeyedWeakReference 到要被监控的对象。
2.然后在后台线程检查引用是否被清除,如果没有,调用GC。
3.如果引用还是未被清除,把 heap 内存 dump 到 APP 对应的文件系统中的一个 .hprof 文件中。
4.在另外一个进程中的 HeapAnalyzerService 有一个 HeapAnalyzer 使用HAHA 解析这个文件。
5.得益于唯一的 reference key, HeapAnalyzer 找到 KeyedWeakReference,定位内存泄漏。
6.HeapAnalyzer 计算 到 GC roots 的最短强引用路径,并确定是否是泄漏。如果是的话,建立导致泄漏的引用链。
7.引用链传递到 APP 进程中的 DisplayLeakService, 并以通知的形式展示出来。
-- 检测内存泄漏框架
集成LeakCanary1.6.3 Android
Leakcanary是square公司开源的一款内存监测框架,https://github.com/square/leakcanary
dependencies {
debugImplementation 'com.squareup.leakcanary:leakcanary-android:1.6.3'
releaseImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.6.3'
// Optional, if you use support library fragments:
debugImplementation 'com.squareup.leakcanary:leakcanary-support-fragment:1.6.3'
}
public class ExampleApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
if (!LeakCanary.isInAnalyzerProcess(this)) {
// This process is dedicated to LeakCanary for heap analysis.
// You should not init your app in this process.
// return;
LeakCanary.install(this);
}
}
}
-- 性能优化
LeakCanary 内存泄漏检测工具;
ACRA Android应用程序崩溃报告。
> Gson数据解析和XML解析
-- Gson使用了注解和反射
> 数据库操作,greendao
ORM就是把数据库表的行与相应的对象建立关联,互相转换。对象关系映射(Object Relation Mapping),是一种程序设计技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换。从效果上说,它其实是创建了一个可在编程语言里使用的“虚拟对象数据库”。
ORM技术中Property类,根据Key获得Value。JDK 中的 Properties 类 Properties 类存在于胞 Java.util 中,该类继承自 Hashtable ,它提供了几个主要的方法:
1.getProperty ( String key) ,用指定的键在此属性列表中搜索属性。也就是通过参数 key ,得到 key 所对应的 value。
2.load ( InputStream inStream) ,从输入流中读取属性列表(键和元素对)。通过对指定的文件(比如说上面的 test.properties 文件)进行装载来获取该文件中的所有键 - 值对。以供 getProperty ( String key) 来搜索。
3.setProperty ( String key, String value) ,调用 Hashtable 的方法 put 。他通过调用基类的put方法来设置 键 - 值对。
4.store ( OutputStream out, String comments) ,以适合使用 load 方法加载到 Properties 表中的格式,将此 Properties 表中的属性列表(键和元素对)写入输出流。与 load 方法相反,该方法将键 - 值对写入到指定的文件中去。
5.clear () ,清除所有装载的 键 - 值对。该方法在基类中提供。
> 网络框架 OkHttp
Interceptor 是 OkHttp 最核心的一个东西,不要误以为它只负责拦截请求进行一些额外的处理(例如 cookie),实际上它把实际的网络请求、缓存、透明压缩等功能都统一了起来,每一个功能都只是一个 Interceptor,它们再连接成一个 Interceptor.Chain,环环相扣,最终圆满完成一次网络请求。
责任链拦截器Interceptor:
RetryAndFollowUpInterceptor:负责失败重试以及重定向;
BridgeInterceptor:负责把用户构造的请求转换为发送到服务器的请求、把服务器返回的响应转换为用户友好的响应的;
ConnectInterceptor:建立连接;
NetworkInterceptors:配置OkHttpClient时设置的 NetworkInterceptors;
CallServerInterceptor:发送和接收数据;
Http请求行:由请求方法,URL,协议版本三部分构成,之间用空格隔开;请求方法包括:POST、GET、HEAD、PUT、POST、TRACE、OPTIONS、DELETE等;
-- Okhttp使用了DiskLruCache(DiskLruCache->LinkedHashMap)
> 图片框架 Picasso、Fresco、Glide
图片框架:Picasso、Fresco、Glide、Android-Universal-Image-Loader
图片函数库的选择需要根据APP的具体情况而定,对于严重依赖图片缓存的APP,例如壁纸类,图片社交类APP来说,可以选择最专业的Fresco。对于一般的APP,选择Fresco会显得比较重,毕竟Fresco 3.4MB的体量摆在这。
根据APP对图片显示和缓存的需求从低到高我们可以对以上函数库做一个排序:
BitmapFun < Picasso < Android-Universal-Image-Loader < Glide < Fresco
-- Glide库图片池:
4.4以前是Bitmap复用必须长宽相等才可以复用;4.4及以后是Size>=所需就可以复用,只不过需要调用reconfigure来调整尺寸;
Glide用AttributeStategy和SizeStrategy来实现两种策略;图片池在收到传来的Bitmap之后,通过长宽或者Size来从KeyPool中获取Key(对象复用到了极致,连Key都用到了Pool),然后再每个Key对应一个双向链表结构来存储。每个Key下可能有很多个待用Bitmap;
取出后要减少图片池中记录的当前Size等,并对Bitmap进行eraseColor(Color.TRANSPAENT)操作确保可用;
-- Glide加载资源:
GlideBuilder在初始化Glide时,会生成一个执行机Engine,Engine中包含LruCache缓存及一个当前正在使用的active资源Cache(弱引用);
activeCache辅助LruCache,当Resource从LruCache中取出使用时,会从LruCache中remove并进入acticeCache当中,
Cache优先级LruCache>activeCache;
Engine在初始化时要传入两个ExecutorService,即会有两个线程池,一个用来从DiskCache获取resource,另一个用来从Source中获取(通常是下载);
线程的封装单位是EngineJob,有两个顺序状态,先是CacheState,在此状态先进入DiskCacheService中执行获取,如果没找到则进入SourceState,进到SourceService中执行下载。
-- Fresco图片框架
三级缓存:内存缓存/磁盘缓存/网络获取图片。
更好的去理解Fresco的实现,还是要从 整体入手,了解它的模块和层次划分,层层推进,逐个理解,才能达到融会贯通的效果。
磁盘缓存因为涉及到文件读写要比内存缓存复杂一些,从下至上可以将磁盘缓存分为三层:
缓冲缓存层:由BufferedDiskCache实现,提供缓冲功能。
文件缓存层:由DiskStroageCache实现,提供实际的缓存功能。
文件存储层:由DefaultDiskStorage实现,提供磁盘文件读写的功能。
-- 图片缓存的原理:实现图片缓存也不难,需要有相应的cache策略。这里采用 内存(memory)-本地(local)-网络(Internet) 三层cache机制,其中内存缓存包括强引用缓存和软引用缓存(SoftReference),其实网络不算cache,这里姑且也把它划到缓存的层次结 构中。当根据url向网络拉取图片的时候,先从内存中找,如果内存中没有,再从本地缓存文件中查找,如果缓存文件中也没有,再从网络上通过http请求拉取图 片。在键值对(key-value)中,这个图片缓存的key是图片url的hash值,value就是bitmap。所以,按照这个逻辑,只要一个 url被下载过,其图片就被缓存起来了。
> 缓存LRU, LruCache, DiskLruCache RobospiceJson
LRU 是 Least Recently Used 最近最少使用算法。缓存使用DBFlow ORM框架。
曾经,在各大缓存图片的框架没流行的时候。有一种很常用的内存缓存技术:SoftReference 和 WeakReference(软引用和弱引用)。但是走到了 Android 2.3(Level 9)时代,垃圾回收机制更倾向于回收 SoftReference 或 WeakReference 的对象。后来,又来到了 Android3.0,图片缓存在内容中,因为不知道要在是什么时候释放内存,没有策略,没用一种可以预见的场合去将其释放。这就造成了内存溢出。
LruCache 就是 利用 LinkedHashMap 的一个特性( accessOrder=true 基于访问顺序 )再加上对 LinkedHashMap 的数据操作上锁实现的缓存策略。DiskLruCache底层也使用了LinkedHashMap实现。
LruCache-https://github.com/CaMnter/AndroidLife/blob/master/app/src/main/java/com/camnter/newlife/utils/cache/LruCache.java
-- LrhCache算法的算法核心 = LRU 算法 + LinkedHashMap数据结构,LinkedHashMap数据结构 = 数组 +单链表 + 双向链表 ;
采用 LRU 算法的缓存类型:内存缓存(LrhCache) 、 硬盘缓存(DisLruCache);
> 图表
WilliamChart,创建图表的Android库;
HelloCharts,兼容到API8的Android图表库;
MPAndroidChart,一个强大的Android图表视图/图形库;
> 后台处理
Tape,一个轻快的,事务性的,基于文件的FIFO的库;
Android Priority Job Queue,一个专门为Android轻松调度任务的工作队列。
> 事件总线: EventBus, Otto
EventBus,安卓优化的事件总线,简化了活动、片段、线程、服务等的通信;Otto,一个基于Guava的增强的事件总线;
消息传递:EventBus.在Android开发中,组件间的通信或者前后端线程之间的通信都是通过持有引用的回调或者Handler来实现的。EventBus是近年来在Android开发中非常常用的一个通信框架,利用它可以很轻易地实现组件与组件之间的各种通信,无论跨线程与否。
EventBus比较适合仅仅当做组件间的通讯工具使用,主要用来传递消息。使用EventBus可以避免搞出一大推的interface,仅仅是为了实现组件间的通讯,而不得不去实现那一推的接口。
RxJava和EventBus一样也是基于观察者模式,但是使用的场景确实异步数据流的处理。
EventBus定义:是一个发布 / 订阅的事件总线。这么说应该包含4个成分:发布者,订阅者,事件,总线,作用是发布/订阅事件总线,因为项目中用到RxJava、RxAndroid,所以完全可以使用RxJava、RxAndroid来实现EventBus。
-- RxJava的原理是一个高度解耦的观察者模式。
> 响应式编程,Rxjava Rxbus
RxJava JVM上的响应式扩展;
RxJavaJoins 为RxJava提供Joins操作;
RxAndroid Android上的响应式扩展,在RxJava基础上添加了Android线程调度;
RxBinding 提供用RxJava绑定Android UI的API;
Agera Android上的响应式编程;
1、RxJava有大量丰富强大的operator,可以满足用户的大部分数据处理需求。RxJava另一个强大的地方就是scheduler,用户可以为Observable和Subscriber指定不同的执行线程,在Android中可以方便的将Observable指定在IO线程中运行,Subscriber在UI线程中运行。
2、RxJava和EventBus一样也是基于观察者模式,但是使用的场景确实异步数据流的处理。
RxJava 有四个基本概念:Observable (可观察者,即被观察者)、 Observer (观察者)、 subscribe (订阅)、事件。Observable 和 Observer 通过 subscribe() 方法实现订阅关系,从而 Observable 可以在需要的时候发出事件来通知 Observer。
Rx是响应式编程的意思, 本质是观察者模式, 是以观察者(Observer)和订阅者(Subscriber)为基础的异步响应方式. 在Android编程时, 经常会使用后台线程, 那么就可以使用这种方式.
-- RxJava
1.Observable和Subscriber可以做任何事情
Observable可以是一个数据库查询,Subscriber用来显示查询结果;Observable可以是屏幕上的点击事件,Subscriber用来响应点击事件;Observable可以是一个网络请求,Subscriber用来显示请求结果。
2.Observable和Subscriber是独立于中间的变换过程的。
在Observable和Subscriber中间可以增减任何数量的map。整个系统是高度可组合的,操作数据是一个很简单的过程。
> 注解框架 bufferknife,依赖注入
1.bufferknife,是注解中相对简单易懂的很不错的开源框架;
2.Dragger2 依赖注入框架,注解,Dragger2解决问题的基本思想是:利用生成和写的代码混合达到看似所有的产生和提供依赖的代码都是手写的样子。
AndroidAnotations ,快速安卓开发。易于维护;
RoboGuice,Android平台的Google Guice;
> 崩溃统计分析crash
Fabric 是一个先进的移动平台平台。 Crashlytics 是Fabric提供的一个崩溃统计分析平台,允许你监控你的应用的状态。
> 监控 推送
百度推送 友盟推送 信鸽推送
> 插件化和热部署
插件化推荐DroidPlugin;
热部署推荐androidFix;
> 测试框架
Mockito Java编写的Mocking单元测试框架
Robotium Android UI 测试
Robolectric Android单元测试框架
Android自带很多测试工具:JUnit,Monkeyrunner,UiAutomator,Espresso等
> 调试框架
Stetho 调试Android应用的桥梁,使得可以利用Chrome开发者工具进行调试