分类目录归档:Android高级

Android高级,分析开源代码,架构与原理

Android如何让APP进程常驻内存?

如何让Android程序常驻内存,像QQ一样拥有强劲的生命力不被系统杀死?它传说中的进程保活(人类也在探索永生不死,App亦然),本文将会介绍进程保活的黑魔法,我想绝大部分开发者都会对它感兴趣。

进程保活的常见方案

黑色保活

何为黑色保活?就是利用不同App进程用广播相互唤醒。例如:

  • 开机、网络切换、拍照、利用系统产生的广播唤醒app。
  • 接入SDK,比如微信SDK会唤醒微信,支付宝SDK会唤醒支付宝。
  • 假如你的手机安装了支付宝,淘宝等阿里系的app,那么你打开任意一个阿里系app后,就可以唤醒其他的阿里系app

    目前Google已经意识到这些问题,所以在Android N中取消了ACTION_NEW_PICTURE,CONNECTIVITY_ACTION等广播。

白色保活

这种进程保活方式非常简单,就是采用系统接口,启动前台Service,这样你会在通知栏看到一个Notification,让用户明确的感知到你在运行中。

灰色保活

这种保活手段目前应用非常广泛,它利用系统漏洞启动一个前台Service,与白色保活的区别在于,它不会在通知栏显示Notification,这样一来用户就无法察觉到运行着一个前台进程,但是你的进程优先级又是高于普通后台进程的。 目前很多app都采用灰色保活手段(微信,QQ),接下来我们一起来验证一下。以微信为例,首先打开微信,然后home键,确认通知栏无Notification,然后进入adb shell执行如下shell命令: dumpsys activity services com.tencent.mm

dumpsys_activity_services

通过以上命令,打印出指定包名进程中的Service信息,你会看到isForeground=true的信息,但是通知栏却没有看到Notification。这就是进程保活的黑魔法。

继续阅读

LeakCanary源码分析第三讲-HeapAnalyzerService详解

前面的两篇文章介绍了LeakCanary的核心架构RefWatcher的工作原理,其核心内容就是查找泄漏对象的最短引用路径,这些工作都是在HeapAnalyzerService中完成的。

HeapAnalyzer

HeapAnalyzerService通过调用HeapAnalyzer的checkForLeak方法来进一步分析内存,使用HAHA将RefWatcher传递过来hprof文件解析成Snapshot对象,其中调用的方法包括SnapshotFactory的parse和HprofIndexBuilder的fill方法。解析得到的SnapShot对象和我们用MAT分析内存得出的对象结构类似,其源码如下:

它构建了一颗对象引用关系树,我们可以在这颗树中查询各个Object的信息,包括Class信息、内存地址、持有的引用以及被持有引用的关系。

继续阅读

LeakCanary源码分析第二讲-RefWatcher详解

如果你已经阅读了LeakCanary源码分析第一讲,那么LeakCanary的基本架构应该已经掌握了。本文将详细分析RefWatcher的工作原理,当RefWatcher检查到引用路径不是弱通路的时候就会触发HeapDumper

WeakReference和ReferenceQueue

要理解RefWatcher的工作原理,首先需要知道WeakReference。当GC线程扫描它所管辖的内存区域时,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否(这一点与SoftReference不同),都会回收它的内存。由于垃圾回收器是一个优先级很低的线程,因此不一定会很快发现那些只具有弱引用的对象。 WeakReference_obj WeakReference和ReferenceQueue联合使用,如果弱引用所引用的对象被垃圾回收,Java虚拟机就会把这个弱引用加入到与之关联的引用队列中。上图中的实线a表示强引用,虚线aa表示弱引用。如果切断a,那么Object对象将会被回收。正如下面这段测试代码所示。 继续阅读

LeakCanary源码分析第一讲

本文将分析LeakCanary源码,介绍LeakCanary核心组件以及LeakCanary注册流程。如果你还不知道LeakCanary是什么,那么请一定要看这篇文章:LeakCanary让Android内存泄漏无处遁形

LeakCanary是Android内存泄漏检测工具,能够将内存泄漏在开发的过程中就暴露出来。

LeakCanary核心组件

LeakCanary-class-diagram 上面的类图可以分为三层来看,第一层包括ActivityRefWatcher、RefWatcher,第三层是Service,第二层是HeapDump.Listener它是用来衔接Watcher与Service的桥梁。 继续阅读

Compile tcpdump for Android Lollipop

       今天发现一个问题,在Android5.0系统下用tcpdump抓包失败,但是在5.0之前的系统上可以正常抓包,报如下错误

       这是由于PIE安全机制所引起的,从Android4.1开始引入该机制,但是Android L之前的系统版本并不会去检验可执行文件是否基于PIE编译出的。因此不会报错。但是Android L已经开启验证,如果调用的可执行文件不是基于PIE方式编译的,则无法运行。解决办法非常简单,编译的时候加上如下的flag就行。

继续阅读