最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android dumpsys簡介

 更新時間:2025年03月11日 09:55:36   作者:林奮斗同學  
本文詳細介紹了Android系統(tǒng)中的dumpsys工具,包括其原理、使用方法、環(huán)境要求和相關概念,dumpsys是一個強大的系統(tǒng)診斷工具,可以幫助開發(fā)者了解系統(tǒng)服務狀態(tài),分析問題,并設計新功能,感興趣的朋友一起看看吧

一、需求

  • 了解dumpsys原理,助于我們進一步了解Android系統(tǒng)的設計
  • 幫助我們分析問題,定位系統(tǒng)狀態(tài)
  • 設計新功能的需要

二、環(huán)境

  • 版本:Android 12
  • 平臺:SL8541E SPRD

三、相關概念

3.1 dumpsys

dumpsys 是一種在 Android 設備上運行的工具,可提供有關系統(tǒng)服務的信息??梢允褂?Android 調試橋 (adb) 從命令行調用 dumpsys,獲取在連接的設備上運行的所有系統(tǒng)服務的診斷輸出。

3.2 Binder

Binder是Android提供的一套進程間相互通信框架。用來實現(xiàn)多進程間發(fā)送消息,同步和共享內存。

請?zhí)砑訄D片描述

3.3 管道

管道是一種IPC通信方式,分為有名管道和無名管道,無論是有名管道還是無名管道其原理都是在內核開辟一塊緩存空間,這段緩存空間的操作是通過文件讀寫方式進行的。
有名管道與無名管道:
有名管道: 有名管道的通信可以通過管道名進行通信,進程間不需要有關系。
無名管道: 無名管道就是匿名管道,匿名管道通信的進程必須是父子進程。
管道為分半雙工和全雙工:
半雙工: 半雙工管道是單向通信,進程1只能向管道寫數(shù)據(jù),進程2只能從管道讀取數(shù)據(jù)。只有一個代表讀或者寫的FD(文件描述符)。
全雙工: 全雙工管道是雙向通信,有兩個文件描述符,代表讀和寫。

請?zhí)砑訄D片描述

四、dumpsys指令的使用

4.1 dumpsys使用

如下為執(zhí)行"adb shell dumpsys"指令,控制臺打印的內容,其使用如下:

dumpsys執(zhí)行

4.2 dumpsys指令語法

(1)使用 dumpsys 的一般語法如下:

adb shell dumpsys [-t timeout] [--help | -l | --skip services | service [arguments] | -c | -h]

(2)如需獲取所連接設備的所有系統(tǒng)服務的診斷輸出,請運行 adb shell dumpsys。不過,這樣輸出的信息比您通常想要的信息多得多。若要使輸出更加可控,您可以通過在命令中添加相應服務來指定要檢查的服務。例如,下面的命令會提供輸入組件(如觸摸屏或內置鍵盤)的系統(tǒng)數(shù)據(jù):

adb shell dumpsys input

(3)如需查看可與 dumpsys 配合使用的系統(tǒng)服務的完整列表,請使用以下命令:

adb shell dumpsys -l

(4)命令行選項如下:

選項說明
-t timeout指定超時期限(秒)。如果未指定,默認值為 10 秒。
–help輸出 dumpsys 工具的幫助文本。
-l輸出可與 dumpsys 配合使用的系統(tǒng)服務的完整列表。
–skip services指定您不希望包含在輸出中的 services。
service [arguments]指定您希望輸出的 service。某些服務可能允許您傳遞可選 arguments。如需了解這些可選參數(shù),請將 -h 選項與服務一起傳遞:
adb shell dumpsys procstats -h
-c指定某些服務時,附加此選項能以計算機可讀的格式輸出數(shù)據(jù)。
-h對于某些服務,附加此選項可查看該服務的幫助文本和其他選項。

五、詳細設計

5.1 dumpsys流程圖

請?zhí)砑訄D片描述

5.2 dumpsys查看電池信息

5.2.1 dumpsys battery指令

請?zhí)砑訄D片描述

5.2.2 service->dump打印函數(shù)

@frameworks\base\services\core\java\com\android\server\BatteryService.java
private final class BinderService extends Binder {
    @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
        if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
            if (args.length > 0 && "--proto".equals(args[0])) {
                dumpProto(fd);
            } else {
                dumpInternal(fd, pw, args);
            }
        }
    ...
}
private void dumpInternal(FileDescriptor fd, PrintWriter pw, String[] args) {
    synchronized (mLock) {
        if (args == null || args.length == 0 || "-a".equals(args[0])) {
            pw.println("Current Battery Service state:");
            if (mUpdatesStopped) {
                pw.println("  (UPDATES STOPPED -- use 'reset' to restart)");
            }
            pw.println("  AC powered: " + mHealthInfo.chargerAcOnline);
            pw.println("  USB powered: " + mHealthInfo.chargerUsbOnline);
            pw.println("  Wireless powered: " + mHealthInfo.chargerWirelessOnline);
            pw.println("  Max charging current: " + mHealthInfo.maxChargingCurrent);
            pw.println("  Max charging voltage: " + mHealthInfo.maxChargingVoltage);
            pw.println("  Charge counter: " + mHealthInfo.batteryChargeCounter);
            pw.println("  status: " + mHealthInfo.batteryStatus);
            pw.println("  health: " + mHealthInfo.batteryHealth);
            pw.println("  present: " + mHealthInfo.batteryPresent);
            pw.println("  level: " + mHealthInfo.batteryLevel);
            pw.println("  scale: " + BATTERY_SCALE);
            pw.println("  voltage: " + mHealthInfo.batteryVoltage);
            pw.println("  temperature: " + mHealthInfo.batteryTemperature);
            pw.println("  technology: " + mHealthInfo.batteryTechnology);
        } else {
            Shell shell = new Shell();
            shell.exec(mBinderService, null, fd, null, args, null, new ResultReceiver(null));
        }
    }
}

5.3 dumpsys源碼分析

5.3.1 dumpsys服務編譯

dumpsys是個二進制可執(zhí)行程序,其通過bp進行編譯,并最終打包到system分區(qū)(system/bin/dumpsys)。

@frameworks\native\cmds\dumpsys\android.bp
cc_binary {
    name: "dumpsys",
    defaults: ["dumpsys_defaults"],
    srcs: [
        "main.cpp",
    ],
}

5.3.2 dumpsys入口函數(shù)

我們通過執(zhí)行adb指令 “adb shell dumpsys”,可以啟動dumpsys服務,其對應的入口函數(shù)如下:

@frameworks\native\cmds\dumpsys\main.cpp
int main(int argc, char* const argv[]) {
    signal(SIGPIPE, SIG_IGN);
    sp<IServiceManager> sm = defaultServiceManager();//獲取SM對象
    fflush(stdout);
    if (sm == nullptr) {
        ALOGE("Unable to get default service manager!");
        std::cerr << "dumpsys: Unable to get default service manager!" << std::endl;
        return 20;
    }
    Dumpsys dumpsys(sm.get());
    return dumpsys.main(argc, argv);//進入dumpsys服務
}

這邊比較關鍵的點是獲取ServiceManager對象
大家通過打印可以發(fā)現(xiàn),dumpsys指令打印的數(shù)據(jù)是java進程的dump函數(shù),而dumpsys也是獨立的一個進程,那么dumpsys進程又是怎么和多個java進程通信的呢?沒錯,就是通過ServiceManager對象。
那么,ServiceManager對象是什么呢?ServiceManager是Binder IPC通信的管家,本身也是一個Binder服務,他相當于 “DNS服務器”,內部存儲了serviceName與其Binder Service的對應關系,管理Java層和native層的service,支持addService()、getService()、checkService、listServices()等功能。(Binder機制此處就不展開細說)

5.3.3 dumpsys服務打印

5.3.3.1 dumpsys解析參數(shù)

當我們使用dumpsys指令,打印的數(shù)據(jù)太過冗長,一般會配合相關參數(shù)進行使用,例如:“dumpsys -l”、“dumpsys -t 100 battery”、“dumpsys --help”,第一步我們會先解析目標參數(shù)。

@frameworks\native\cmds\dumpsys\dumpsys.cpp
int Dumpsys::main(int argc, char* const argv[]) {
    ...
    while (1) {
        ...
        c = getopt_long(argc, argv, "+t:T:l", longOptions, &optionIndex);//獲取指令參數(shù)
        ...
        switch (c) {
        case 0://長參數(shù)
            if (!strcmp(longOptions[optionIndex].name, "skip")) {//跳過某些服務打印
                skipServices = true;
            } else if (!strcmp(longOptions[optionIndex].name, "proto")) {
                asProto = true;
            } else if (!strcmp(longOptions[optionIndex].name, "help")) {//指令幫助
                usage();
                return 0;
            } else if (!strcmp(longOptions[optionIndex].name, "priority")) {
                ...
            } else if (!strcmp(longOptions[optionIndex].name, "pid")) {//只顯示服務的pid
                type = Type::PID;
            } else if (!strcmp(longOptions[optionIndex].name, "thread")) {//僅顯示進程使用情況
                type = Type::THREAD;
            }
            break;
        case 't'://超時時間設置,默認10秒
            ...
            break;
        case 'T'://超時時間設置,默認10秒
            ...
            break;
        case 'l'://顯示支持的服務列表
            showListOnly = true;
            break;
        default://其他參數(shù)
            fprintf(stderr, "\n");
            usage();
            return -1;
        }
    }
    ...
}

5.3.3.2 skippedServices列表構造

dumpsys內部構造了skippedServices集合,用于記錄需要忽略的服務。

@frameworks\native\cmds\dumpsys\dumpsys.cpp
int Dumpsys::main(int argc, char* const argv[]) {
    ...
    for (int i = optind; i < argc; i++) {
    if (skipServices) {
        skippedServices.add(String16(argv[i]));//配置待忽略的服務
    } else {
        ...
    }
    ...
}

5.3.3.3 獲取支持服務列表

dumpsys通過ServiceManager獲取支持的服務集合,并排序。

@frameworks\native\cmds\dumpsys\dumpsys.cpp
int Dumpsys::main(int argc, char* const argv[]) {
    ...
    if (services.empty() || showListOnly) {
        services = listServices(priorityFlags, asProto);
        setServiceArgs(args, asProto, priorityFlags);
    }
    ...
}
Vector<String16> Dumpsys::listServices(int priorityFilterFlags, bool filterByProto) const {
    Vector<String16> services = sm_->listServices(priorityFilterFlags);//通過sm獲取服務集合
    services.sort(sort_func);//集合排序
    ...
    return services;
}

5.3.3.4 打印支持服務列表

在獲取了服務集合后,會先檢查服務是否存在,接著打印服務的名稱,且如果當前指令設置了"-l"參數(shù),僅打印服務集合,即流程結束。

@frameworks\native\cmds\dumpsys\dumpsys.cpp
int Dumpsys::main(int argc, char* const argv[]) {
    ...
    const size_t N = services.size();//獲取支持的服務個數(shù)
    if (N > 1 || showListOnly) {
        // first print a list of the current services
        std::cout << "Currently running services:" << std::endl;
        for (size_t i=0; i<N; i++) {
            sp<IBinder> service = sm_->checkService(services[i]);//檢查服務狀態(tài)
            if (service != nullptr) {
                bool skipped = IsSkipped(skippedServices, services[i]);
                std::cout << "  " << services[i] << (skipped ? " (skipped)" : "") << std::endl;//打印服務名稱
            }
        }
    }
    if (showListOnly) {//如果指令僅需要打印服務集合,則結束。
        return 0;
    }
    ...
}

5.3.3.5 打印目標服務

先遍歷所有需要打印的服務,如果參數(shù)有指定服務名,即N為對應服務的數(shù)量,否則N為所有支持的服務數(shù)量。接著,開啟線程,通過servicemanager調用遠端的dump函數(shù),利用管道和poll機制監(jiān)聽遠端數(shù)據(jù)。最后如果超時或者dump結束,則關閉線程,釋放相關資源。

@frameworks\native\cmds\dumpsys\dumpsys.cpp
int Dumpsys::main(int argc, char* const argv[]) {
    ...
    for (size_t i = 0; i < N; i++) {
        const String16& serviceName = services[i];
        if (IsSkipped(skippedServices, serviceName)) continue;//跳過部分服務
        if (startDumpThread(type, serviceName, args) == OK) {//step 1.創(chuàng)建dump打印的線程
            ...
            std::chrono::duration<double> elapsedDuration;
            size_t bytesWritten = 0;
            status_t status =
                writeDump(STDOUT_FILENO, serviceName, std::chrono::milliseconds(timeoutArgMs),
                          asProto, elapsedDuration, bytesWritten);//step 2.dump執(zhí)行打印操作
            if (status == TIMED_OUT) {//打印超時
                std::cout << std::endl
                     << "*** SERVICE '" << serviceName << "' DUMP TIMEOUT (" << timeoutArgMs
                     << "ms) EXPIRED ***" << std::endl
                     << std::endl;
            }
            ...
            bool dumpComplete = (status == OK);
            stopDumpThread(dumpComplete);//step 3.結束dump打印線程
        }
    }
    ...
}

step 1. 創(chuàng)建dumpsys打印線程
創(chuàng)建了一條管道,接著開啟了一個線程,通過ServiceManager對象讀取目標服務的dump函數(shù),即dump打印數(shù)據(jù)。

@frameworks\native\cmds\dumpsys\dumpsys.cpp
status_t Dumpsys::startDumpThread(Type type, const String16& serviceName,
                                  const Vector<String16>& args) {
    sp<IBinder> service = sm_->checkService(serviceName);//通過SM獲取service對象
    int sfd[2];
    if (pipe(sfd) != 0) {//創(chuàng)建管道,用于讀取service端數(shù)據(jù)
        ...
    }
    ...
    redirectFd_ = unique_fd(sfd[0]);
    unique_fd remote_end(sfd[1]);
    sfd[0] = sfd[1] = -1;
    // dump blocks until completion, so spawn a thread..
    activeThread_ = std::thread([=, remote_end{std::move(remote_end)}]() mutable {//創(chuàng)建線程
        status_t err = 0;
        switch (type) {
        case Type::DUMP:
            err = service->dump(remote_end.get(), args);//調用dump函數(shù)
            break;
        ...
        }
        ...
    });
    return OK;
}

step 2. dumpsys打印到終端
通過poll機制用來監(jiān)聽管道的數(shù)據(jù),并將讀取到的dump數(shù)據(jù),打印至控制臺。同時,通過計算剩余的時間,來判斷當前是否讀取超時。

@frameworks\native\cmds\dumpsys\dumpsys.cpp
status_t Dumpsys::writeDump(int fd, const String16& serviceName, std::chrono::milliseconds timeout,
                            bool asProto, std::chrono::duration<double>& elapsedDuration,
                            size_t& bytesWritten) const {
    ...
    int serviceDumpFd = redirectFd_.get();
    struct pollfd pfd = {.fd = serviceDumpFd, .events = POLLIN};
    while (true) {
        ...
        int rc = TEMP_FAILURE_RETRY(poll(&pfd, 1, time_left_ms()));//poll機制檢測管道數(shù)據(jù)
        if (rc < 0) {
           ...
        } else if (rc == 0 || time_left_ms() == 0) {
            status = TIMED_OUT;//計算剩余時間,來決定是否超時
            break;
        }
        char buf[4096];
        rc = TEMP_FAILURE_RETRY(read(redirectFd_.get(), buf, sizeof(buf)));//讀取遠端的數(shù)據(jù)
        ...
        if (!WriteFully(fd, buf, rc)) {//打印至控制臺
            ...
            break;
        }
        totalBytes += rc;
    }
    ...
    return status;
}

step 3. 關閉dumpsys打印線程
將dumpsys打印的線程detach掉,相關的fd句柄reset掉,釋放資源。

六、dumpsys的應用

如后續(xù)有什么應用dumpsys,或者有助于日常開發(fā)調試的場景,再補充,未完待續(xù)。

6.1 dumpsys常用指令

服務名類名指令功能
activityActivityManagerService獲取某個應用的Activity信息:
adb shell dumpsys activity a packagename
獲取某個應用的Service信息:
adb shell dumpsys activity s packagename
獲取某個應用的Broadcast信息:
adb shell dumpsys activity b packagename
獲取某個應用的Provider信息:
adb shell dumpsys activity prov packagename
獲取某個應用的進程狀態(tài):
adb shell dumpsys activity p packagename
獲取當前界面的Activity信息:
adb shell dumpsys activity top | grep ACTIVITY
AMS相關信息
packagePackageManagerServiceadb shell dumpsys packagePMS相關信息
windowWindowManagerServiceadb shell dumpsys windowWMS相關信息
inputInputManagerServiceadb shell dumpsys inputIMS相關信息
powerPowerManagerServiceadb shell dumpsys powerPMS相關信息
batterystatsBatterystatsServiceadb shell dumpsys batterystats電池統(tǒng)計信息
batteryBatteryServiceadb shell dumpsys battery電池信息
alarmAlarmManagerServiceadb shell dumpsys alarm鬧鐘信息
dropboxDropboxManagerServiceadb shell dumpsys dropbox調試相關
procstatsProcessStatsServiceadb shell dumpsys procstats進程統(tǒng)計
cpuinfoCpuBinderadb shell dumpsys cpuinfoCPU
meminfoMemBinderadb shell dumpsys meminfo內存
gfxinfoGraphicsBinderadb shell dumpsys gfxinfo圖像
dbinfoDbBinderadb shell dumpsys dbinfo數(shù)據(jù)庫

七、參考資料

dumpsys指令介紹:
https://developer.android.google.cn/studio/command-line/dumpsys?hl=zh-cn
管道:
https://www.cnblogs.com/naray/p/15365954.html
Binder:
https://blog.csdn.net/shenxiaolinil/article/details/128972302

到此這篇關于Android dumpsys簡介的文章就介紹到這了,更多相關Android dumpsys內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Android Studio一直處于Building的兩種解決方法

    Android Studio一直處于Building的兩種解決方法

    很多朋友都遇到過打開別人的項目一直處于Building‘XXX’Gradle project info的情況。下面小編給大家?guī)砹薃ndroid Studio一直處于Building的解決方法,感興趣的朋友一起看看吧
    2018-08-08
  • Jetpack?Compose重寫TopAppBar實現(xiàn)標題多行折疊詳解

    Jetpack?Compose重寫TopAppBar實現(xiàn)標題多行折疊詳解

    這篇文章主要為大家介紹了Jetpack?Compose重寫TopAppBar實現(xiàn)標題多行折疊示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-11-11
  • Android 開發(fā)實例簡單涂鴉板

    Android 開發(fā)實例簡單涂鴉板

    本文主要介紹 Android 簡單涂鴉板,這里提供了代碼示例和實現(xiàn)效果圖,有興趣的小伙伴可以參考下
    2016-08-08
  • Android自定義控件實現(xiàn)餅狀圖

    Android自定義控件實現(xiàn)餅狀圖

    這篇文章主要為大家詳細介紹了Android自定義控件實現(xiàn)餅狀圖,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-12-12
  • Android自動縮放上下限折線圖示例

    Android自動縮放上下限折線圖示例

    這篇文章主要為大家介紹了Android?自動縮放上下限的折線圖示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-08-08
  • Android DrawerLayout實現(xiàn)抽屜效果實例代碼

    Android DrawerLayout實現(xiàn)抽屜效果實例代碼

    這篇文章主要介紹了Android DrawerLayout實現(xiàn)抽屜效果的實例代碼,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2016-12-12
  • Android實現(xiàn)靜默拍照功能

    Android實現(xiàn)靜默拍照功能

    這篇文章主要為大家詳細介紹了Android實現(xiàn)靜默拍照,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-06-06
  • android編程實現(xiàn)為程序創(chuàng)建快捷方式的方法

    android編程實現(xiàn)為程序創(chuàng)建快捷方式的方法

    這篇文章主要介紹了android編程實現(xiàn)為程序創(chuàng)建快捷方式的方法,實例分析了Android創(chuàng)建程序快捷方式的相關設置與功能實現(xiàn)技巧,需要的朋友可以參考下
    2015-11-11
  • Flutter實現(xiàn)二維碼掃描

    Flutter實現(xiàn)二維碼掃描

    這篇文章主要為大家詳細介紹了Flutter實現(xiàn)二維碼掃描,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-04-04
  • Android仿微信網(wǎng)絡加載彈出框

    Android仿微信網(wǎng)絡加載彈出框

    這篇文章主要為大家詳細介紹了Android仿微信網(wǎng)絡加載彈出框,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-06-06

最新評論

南宫市| 桂东县| 云阳县| 徐闻县| 甘南县| 宝清县| 天津市| 金华市| 黄浦区| 宜良县| 老河口市| 阿荣旗| 河曲县| 华坪县| 荣成市| 南丰县| 丽水市| 中江县| 太谷县| 辉南县| 出国| 武安市| 阳高县| 泽普县| 泾川县| 平陆县| 周至县| 成武县| 昭苏县| 韶山市| 鲁甸县| 耒阳市| 建水县| 梁河县| 湖北省| 二连浩特市| 出国| 土默特左旗| 贵南县| 阿坝| 新巴尔虎右旗|