温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Android Bitmap Monitor图片定位功能怎么实现

发布时间:2023-05-11 15:12:05 来源:亿速云 阅读:92 作者:iii 栏目:开发技术

本篇内容介绍了“Android Bitmap Monitor图片定位功能怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

    正文

    在日常工作中,我们往往只关注 Java 内存使用情况,这主要是因为 Java 内存分析相关的工具比较多。与之不同的是,图片内存分析的工具比较少,当分析图片内存问题时我们需要花费很大的精力。

    我们知道,在 Android 应用使用的内存中,图片总是占据不少比例。拿小米 12 来说,3200 x 1440 的分辨率,一张全屏的图片至少要占用 17MB(3200 x 1440 x 4 )。如果缓存里多几张,基本就要达到上百 MB。加载的图片稍有不当,就可能导致应用的内存溢出崩溃大大增加。

    因此,我们需要这样的工具:可以快速发现应用内加载的图片是否合理,比如大小是否合适、是否存在泄漏、缓存是否及时清理、是否加载了当前并不需要的图片等等。

    AndroidBitmapMonitor 正是为此而生!它是一个开源的 Android 图片内存分析工具,可以帮助开发者快速发现应用的图片使用是否合理,支持在线下和线上使用

    AndroidBitmapMonitor 提供了这些功能:

    • 获取内存中的 Bitmap 数量及占用内存

    • 查看 Bitmap 创建堆栈及线程

    • 导出 Bitmap 图片,帮助直接定位问题所属业务

    • 动态开关,可以在任意时间开始和结束

    功能介绍

    • 支持 Android 4.4 - 13 (API level 19 - 33)

    • 支持 armeabi-v7a 和 arm64-v8a

    • 支持线下实时查看图片内存情况 和 线上数据统计

    可以提供的功能:

    • 获取内存中的图片数量及占用内存

    • 获取 Bitmap 创建堆栈及线程

    • 全版本 Bitmap Preview,在堆栈无法看出问题时,可以用来定位图片所属业务

    使用文档

    主要有四步:

    • 添加 gradle 依赖

    • 初始化配置

    • 在需要的时候调用 start 和 stop

    • 获取数据

    1. 在 build.gradle 中增加依赖

    Android Bitmap Monitor 发布在 mavenCentral 上,因此首先需要确保您的项目有使用 mavenCentral 作为仓库。

    您可以在根目录的 build.gradle 或者 setting.gradle 中添加以下代码:

    allprojects {
        repositories {
            //...
            //添加 mavenCentral 依赖
            mavenCentral()
        }
    }

    接着在具体业务的 build.gradle 文件中添加依赖:

    android {
        packagingOptions {
            pickFirst 'lib/*/libshadowhook.so'
        }
    }
    dependencies {
        implementation 'io.github.shixinzhang:android-bitmap-monitor:1.0.2'
    }

    请注意:为了避免和其他库冲突,上面的 packagingOptions 中 pickFirst 'lib/*/libshadowhook.so' 是必要的。

    添加完依赖并执行 gradle sync 后,下一步就是在代码里进行初始化和启动。

    2. 初始化

    初始化需要调用的 API 是 BitmapMonitor.init

            long checkInterval = 10;
            long threshold = 100 * 1024;
            long restoreImageThreshold = 100 * 1024;;
            String dir = this.getExternalFilesDir("bitmap_monitor").getAbsolutePath();
            BitmapMonitor.Config config = new BitmapMonitor.Config.Builder()
                    .checkRecycleInterval(checkInterval)    //检查图片是否被回收的间隔,单位:秒 (建议不要太频繁,默认 5秒)
                    .getStackThreshold(threshold)           //获取堆栈的阈值,当一张图片占据的内存超过这个数值后就会去抓栈
                    .restoreImageThreshold(restoreImageThreshold)   //还原图片的阈值,当一张图占据的内存超过这个数值后,就会还原出一张原始图片
                    .restoreImageDirectory(dir)             //保存还原后图片的目录
                    .showFloatWindow(true)                  //是否展示悬浮窗,可实时查看内存大小(建议只在 debug 环境打开)
                    .isDebug(true)
                    .context(this)
                    .build();
            BitmapMonitor.init(config);

    当 showFloatWindow 为 true 时,首次启动 app 需要授予悬浮窗权限。

    3. 开启和停止监控

    初始化完成后,可以在任意时刻调用 start/stop 开启和停止监控:

            //开启监控,方式1
            BitmapMonitor.start();
            //开启方式2,提供页面获取接口,建议使用
            BitmapMonitor.start(new BitmapMonitor.CurrentSceneProvider() {
                @Override
                public String getCurrentScene() {
                    //返回当前顶部页面名称
                    if (sCurrentActivity != null) {
                        return sCurrentActivity.getClass().getSimpleName();
                    }
                    return null;
                }
            });
            //停止监控
            BitmapMonitor.stop();

    上面的代码中,开启方式 2 的参数用来获取图片创建时的页面名称,这个接口可以帮助知道大图是在哪个页面创建的。如果不想提供这个接口可以使用开启方式 1。

    那我们该在什么使用开启监控呢?

    一般有「全局开启」和「分业务开启」两种使用方式:

    • 全局开启:一启动就 start,用于了解整个 APP 使用过程中的图片内存数据

    • 分业务开启:在进入某个业务前 start,退出后 stop,用于了解特定业务的图片内存数据

    4. 获取数据

    在初始化完成并开启监控后,我们就可以拦截到每张图片的创建过程。

    Android Bitmap Monitor 提供了两种获取内存中图片数据的 API:

    • 定时回调 addListener

    • 主动获取数据 dumpBitmapInfo

    定时回调 是指注册一个 listener,这个接口的回调会按照一定时间间隔被调用,可以用来做实时监控

            BitmapMonitor.addListener(new BitmapMonitor.BitmapInfoListener() {
                @Override
                public void onBitmapInfoChanged(final BitmapMonitorData data) {
                    Log.d("bitmapmonitor", "onBitmapInfoChanged: " + data);
                }
            });

    间隔时间是初始化时传递的参数 checkRecycleInterval,返回的数据结构如下所示:

    public class BitmapMonitorData {
        //历史创建的总图片数
        public long createBitmapCount;
        //历史创建的总图片内存大小,单位 byte
        public long createBitmapMemorySize;
        //当前内存中还未回收的图片数
        public long remainBitmapCount;
        //当前内存中还未回收的图片内存大小,单位 byte
        public long remainBitmapMemorySize;
        //泄漏(未释放)的 bitmap 数据
        public BitmapRecord[] remainBitmapRecords;
        //...
    }

    主动获取数据 是指主动调用 BitmapMonitor.dumpBitmapInfo() 获取内存中的所有数据,可以用在内存升高时上报数据

            //获取所有数据
            BitmapMonitorData bitmapAllData = BitmapMonitor.dumpBitmapInfo();
            Log.d("bitmapmonitor", "bitmapAllData: " + bitmapAllData);
            //仅获取数量和内存大小,不获取具体图片信息
            BitmapMonitorData bitmapCountData = BitmapMonitor.dumpBitmapCount();
            Log.d("bitmapmonitor", "bitmapCountData: " + bitmapCountData);

    dumpBitmapInfo 会返回内存中所有图片的信息,如果只想获取到图片的总数和内存总量,可以调用 dumpBitmapCount,速度更快更轻量。

    “Android Bitmap Monitor图片定位功能怎么实现”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!

    向AI问一下细节

    免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

    AI