DropBox系列-安卓DropBox介绍

本文介绍了安卓DropBox模块的原理和作用,它用于记录系统异常信息如crash和ANR。DropBox将异常信息存储在data/system/dropbox目录下,并通过binder接口和广播进行信息传递。作者探讨了利用DropBox实现全系统APP稳定性监控的三个方案,并提出这能减少对第三方框架如bugly的依赖,提升性能和稳定性。下文将详细讨论如何构建APM框架。
摘要由CSDN通过智能技术生成

前言:

作者本人负责公司的APM监控模块,因为工作的原因,对ANR,crash等流程研究的比较多,最近在打造APM监控平台的时候,顺带对DropBox的实现原理进行了一定的学习和研究,发现了一些妙用,因此写这篇文章来分享。

本系列分为两篇文章,

1.DropBox系列-安卓DropBox介绍:主要介绍DropBox的一些实现原理。

2.DropBox系列-利用DropBox打造APM框架:主要介绍利用DropBox打造一个面向所有APP的稳定性监控框架。

PS:本文的代码以安卓9(SDK=28)的源码来介绍,因为目前车载开发基本上都是以安卓9为基础来定制的,而且DropBox对于那些拥有系统权限的APP来讲意义更大一些。

一.DropBox简介

dropbox是安卓系统中用来记录一些异常信息的模块,比如某个应用crash了或者anr了,系统最终都会把记录的异常信息记录到dropbox中。

其一般会把异常信息记录到中:data/system/dropbox文件夹下,记录的类型会有很多种,主要有CRASH,ANR,墓碑日志,native崩溃等等,如下图所示:

当然,由于SELinux权限的限制,这些文件夹对于普通的APP来讲说不可访问的,只有拥有系统签名的APP才可以访问的。

二.DropBox记录流程

2.1 binder接口

DropBoxManagerService中,提供了一个binder实现类,主要提供了四个方法,其实最核心的,就是add方法,也就是真正实现记录的方法。我们的源码阅读,也从这里开始。

private final IDropBoxManagerService.Stub mStub = new IDropBoxManagerService.Stub() {
        @Override
        public void add(DropBoxManager.Entry entry) {
            DropBoxManagerService.this.add(entry);
        }

        @Override
        public boolean isTagEnabled(String tag) {
            return DropBoxManagerService.this.isTagEnabled(tag);
        }

        @Override
        public DropBoxManager.Entry getNextEntry(String tag, long millis) {
            return DropBoxManagerService.this.getNextEntry(tag, millis);
        }

        @Override
        public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
            DropBoxManagerService.this.dump(fd, pw, args);
        }
    };

2.2 add流程

binder的add方法之后,会调用到DropBoxManagerService的add方法。

其核心实现逻辑就是add方法,add方法主要做了一下的工作:

1.把接收到的Entry内容写入到临时文件tmp中。

temp = new File(mDropBoxDir, "drop" + Thread.currentThread().getId() + ".tmp");

2.写入完成后,把tmp文件修改文件名,改成data_app_anr@111这样的文件名。

final File file = this.getFile(dir);
            if (!temp.renameTo(file)) {
                throw new IOException("Can't rename " + temp + " to " + file);
            }

3.切换成主线程,发送广播。

final Intent dropboxIntent = new Intent(DropBoxManager.ACTION_DROPBOX_ENTRY_ADDED);
            dropboxIntent.putExtra(DropBoxManager.EXTRA_TAG, tag);
            dropboxIntent.putExtra(DropBoxManager.EXTRA_TIME, time);
            if (!mBooted) {
                dropboxIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
            }
            // Call sendBroadcast after returning from this call to avoid deadlock. In particular
            // the caller may be holding the WindowManagerService lock but sendBroadcast requires a
            // lock in ActivityManagerService. ActivityManagerService has been caught holding that
            // very lock while waiting for the WindowManagerService lock.
            mHandler.sendMessage(mHandler.obtainMessage(MSG_SEND_BROADCAST, dropboxIntent));

三.DropBox妙用

既然在系统发现异常后,会主动把对应的记录文件进行记录,那么,我们是不是可以利用dropbox,针对系统中所有的APP应用进行一个切面编程,捕获所有的异常进行上报。这样就不需要每个应用单独去接入注入bugly一类的框架了,而且由于少了bugly的影响,性能,稳定性会更好。

实现对dropbox的切面编程,主要有以下三个方案:

方案一:监听dropbox文件夹变化

利用FileObserver对data/system/dropbox文件夹进行修改监听,bugly其实也是用的这个原理,6.0以上会因为SELinux的权限失效。所以要对SELinux的文件夹进行配置。

方案二:修改系统源码进行binder通讯

修改系统AMS中的源码,APP进行binder的注册。在发现崩溃或者ANR的之后,利用APP注册的binder,通知APP一侧。

方案三:利用广播进行通知

上面介绍,保存完成后,回发送一个广播。那么我们在APP侧监听这个广播,就可以知道什么时候出现了异常。

具体的实现和结果,我们下一章APM框架再来细细讲解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

失落夏天

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值