溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Android?Bitmap?Monitor圖片定位功能怎么實現(xiàn)

發(fā)布時間:2023-05-11 15:12:05 來源:億速云 閱讀:106 作者:iii 欄目:開發(fā)技術(shù)

本篇內(nèi)容介紹了“Android Bitmap Monitor圖片定位功能怎么實現(xiàn)”的有關(guān)知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

    正文

    在日常工作中,我們往往只關(guān)注 Java 內(nèi)存使用情況,這主要是因為 Java 內(nèi)存分析相關(guān)的工具比較多。與之不同的是,圖片內(nèi)存分析的工具比較少,當(dāng)分析圖片內(nèi)存問題時我們需要花費很大的精力。

    我們知道,在 Android 應(yīng)用使用的內(nèi)存中,圖片總是占據(jù)不少比例。拿小米 12 來說,3200 x 1440 的分辨率,一張全屏的圖片至少要占用 17MB(3200 x 1440 x 4 )。如果緩存里多幾張,基本就要達(dá)到上百 MB。加載的圖片稍有不當(dāng),就可能導(dǎo)致應(yīng)用的內(nèi)存溢出崩潰大大增加。

    因此,我們需要這樣的工具:可以快速發(fā)現(xiàn)應(yīng)用內(nèi)加載的圖片是否合理,比如大小是否合適、是否存在泄漏、緩存是否及時清理、是否加載了當(dāng)前并不需要的圖片等等。

    AndroidBitmapMonitor 正是為此而生!它是一個開源的 Android 圖片內(nèi)存分析工具,可以幫助開發(fā)者快速發(fā)現(xiàn)應(yīng)用的圖片使用是否合理,支持在線下和線上使用。

    AndroidBitmapMonitor 提供了這些功能:

    • 獲取內(nèi)存中的 Bitmap 數(shù)量及占用內(nèi)存

    • 查看 Bitmap 創(chuàng)建堆棧及線程

    • 導(dǎo)出 Bitmap 圖片,幫助直接定位問題所屬業(yè)務(wù)

    • 動態(tài)開關(guān),可以在任意時間開始和結(jié)束

    功能介紹

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

    • 支持 armeabi-v7a 和 arm64-v8a

    • 支持線下實時查看圖片內(nèi)存情況 和 線上數(shù)據(jù)統(tǒng)計

    可以提供的功能:

    • 獲取內(nèi)存中的圖片數(shù)量及占用內(nèi)存

    • 獲取 Bitmap 創(chuàng)建堆棧及線程

    • 全版本 Bitmap Preview,在堆棧無法看出問題時,可以用來定位圖片所屬業(yè)務(wù)

    使用文檔

    主要有四步:

    • 添加 gradle 依賴

    • 初始化配置

    • 在需要的時候調(diào)用 start 和 stop

    • 獲取數(shù)據(jù)

    1. 在 build.gradle 中增加依賴

    Android Bitmap Monitor 發(fā)布在 mavenCentral 上,因此首先需要確保您的項目有使用 mavenCentral 作為倉庫。

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

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

    接著在具體業(yè)務(wù)的 build.gradle 文件中添加依賴:

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

    請注意:為了避免和其他庫沖突,上面的 packagingOptions 中 pickFirst 'lib/*/libshadowhook.so' 是必要的。

    添加完依賴并執(zhí)行 gradle sync 后,下一步就是在代碼里進(jìn)行初始化和啟動。

    2. 初始化

    初始化需要調(diào)用的 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)    //檢查圖片是否被回收的間隔,單位:秒 (建議不要太頻繁,默認(rèn) 5秒)
                    .getStackThreshold(threshold)           //獲取堆棧的閾值,當(dāng)一張圖片占據(jù)的內(nèi)存超過這個數(shù)值后就會去抓棧
                    .restoreImageThreshold(restoreImageThreshold)   //還原圖片的閾值,當(dāng)一張圖占據(jù)的內(nèi)存超過這個數(shù)值后,就會還原出一張原始圖片
                    .restoreImageDirectory(dir)             //保存還原后圖片的目錄
                    .showFloatWindow(true)                  //是否展示懸浮窗,可實時查看內(nèi)存大?。ńㄗh只在 debug 環(huán)境打開)
                    .isDebug(true)
                    .context(this)
                    .build();
            BitmapMonitor.init(config);

    當(dāng) showFloatWindow 為 true 時,首次啟動 app 需要授予懸浮窗權(quán)限。

    3. 開啟和停止監(jiān)控

    初始化完成后,可以在任意時刻調(diào)用 start/stop 開啟和停止監(jiān)控:

            //開啟監(jiān)控,方式1
            BitmapMonitor.start();
            //開啟方式2,提供頁面獲取接口,建議使用
            BitmapMonitor.start(new BitmapMonitor.CurrentSceneProvider() {
                @Override
                public String getCurrentScene() {
                    //返回當(dāng)前頂部頁面名稱
                    if (sCurrentActivity != null) {
                        return sCurrentActivity.getClass().getSimpleName();
                    }
                    return null;
                }
            });
            //停止監(jiān)控
            BitmapMonitor.stop();

    上面的代碼中,開啟方式 2 的參數(shù)用來獲取圖片創(chuàng)建時的頁面名稱,這個接口可以幫助知道大圖是在哪個頁面創(chuàng)建的。如果不想提供這個接口可以使用開啟方式 1。

    那我們該在什么使用開啟監(jiān)控呢?

    一般有「全局開啟」和「分業(yè)務(wù)開啟」兩種使用方式:

    • 全局開啟:一啟動就 start,用于了解整個 APP 使用過程中的圖片內(nèi)存數(shù)據(jù)

    • 分業(yè)務(wù)開啟:在進(jìn)入某個業(yè)務(wù)前 start,退出后 stop,用于了解特定業(yè)務(wù)的圖片內(nèi)存數(shù)據(jù)

    4. 獲取數(shù)據(jù)

    在初始化完成并開啟監(jiān)控后,我們就可以攔截到每張圖片的創(chuàng)建過程。

    Android Bitmap Monitor 提供了兩種獲取內(nèi)存中圖片數(shù)據(jù)的 API:

    • 定時回調(diào) addListener

    • 主動獲取數(shù)據(jù) dumpBitmapInfo

    定時回調(diào) 是指注冊一個 listener,這個接口的回調(diào)會按照一定時間間隔被調(diào)用,可以用來做實時監(jiān)控

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

    間隔時間是初始化時傳遞的參數(shù) checkRecycleInterval,返回的數(shù)據(jù)結(jié)構(gòu)如下所示:

    public class BitmapMonitorData {
        //歷史創(chuàng)建的總圖片數(shù)
        public long createBitmapCount;
        //歷史創(chuàng)建的總圖片內(nèi)存大小,單位 byte
        public long createBitmapMemorySize;
        //當(dāng)前內(nèi)存中還未回收的圖片數(shù)
        public long remainBitmapCount;
        //當(dāng)前內(nèi)存中還未回收的圖片內(nèi)存大小,單位 byte
        public long remainBitmapMemorySize;
        //泄漏(未釋放)的 bitmap 數(shù)據(jù)
        public BitmapRecord[] remainBitmapRecords;
        //...
    }

    主動獲取數(shù)據(jù) 是指主動調(diào)用 BitmapMonitor.dumpBitmapInfo() 獲取內(nèi)存中的所有數(shù)據(jù),可以用在內(nèi)存升高時上報數(shù)據(jù)

            //獲取所有數(shù)據(jù)
            BitmapMonitorData bitmapAllData = BitmapMonitor.dumpBitmapInfo();
            Log.d("bitmapmonitor", "bitmapAllData: " + bitmapAllData);
            //僅獲取數(shù)量和內(nèi)存大小,不獲取具體圖片信息
            BitmapMonitorData bitmapCountData = BitmapMonitor.dumpBitmapCount();
            Log.d("bitmapmonitor", "bitmapCountData: " + bitmapCountData);

    dumpBitmapInfo 會返回內(nèi)存中所有圖片的信息,如果只想獲取到圖片的總數(shù)和內(nèi)存總量,可以調(diào)用 dumpBitmapCount,速度更快更輕量。

    “Android Bitmap Monitor圖片定位功能怎么實現(xiàn)”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!

    向AI問一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI