如何使用 ADB 重定向 Android 應用程式 stdout/stderr?

如何使用 ADB 重定向 Android 應用程式 stdout/stderr?

我想自動化一些 Android 命令列應用程式的更多軟體開發過程。幾年前,我會在實體 Android 裝置上安裝 Busybox,拿來顯微鏡,然後開始在 Android 版 Emacs 中打字。今天,我正在尋找更方便的編碼方式。

特別是,我想重定向 Android (NDK) 應用程式的 stdout 和 stderr 檔案描述符,類似於 qemu-arm64-static 的工作方式。

有誰知道亞銀是否可以這樣做?作為替代方案,我可以將應用程式建置為微服務並使用 ADB 連接埠轉送。但這樣做我會失去很多經典的 UNIX 約定。

我看到 ADB 具有針對 NDK (log.h) 和 SDK (Log.class) 訊息的日誌記錄擷取。但遺憾的是,我沒有看到將主機 STDIN 重定向到 Android 來賓應用程式 STDIN 的明確方法。

也許有一種方法可以透過 adb 觸發 Toybox (mksh) 並在那裡發送自訂 sh 命令?

答案1

各種來源(例如https://stackoverflow.com/a/36561699/340175https://github.com/android/ndk/issues/671#issuecomment-383890481)推薦中所描述的方法https://codelab.wordpress.com/2014/11/03/how-to-use-standard-output-streams-for-logging-in-android-apps/

為了方便後代,該部落格文章中的程式碼如下:

static int pfd[2];
static pthread_t thr;
static const char *tag = "myapp";

int start_logger(const char *app_name)
{
    tag = app_name;

    /* make stdout line-buffered and stderr unbuffered */
    setvbuf(stdout, 0, _IOLBF, 0);
    setvbuf(stderr, 0, _IONBF, 0);

    /* create the pipe and redirect stdout and stderr */
    pipe(pfd);
    dup2(pfd[1], 1);
    dup2(pfd[1], 2);

    /* spawn the logging thread */
    if(pthread_create(&thr, 0, thread_func, 0) == -1)
        return -1;
    pthread_detach(thr);
    return 0;
}

static void *thread_func(void*)
{
    ssize_t rdsz;
    char buf[128];
    while((rdsz = read(pfd[0], buf, sizeof buf - 1)) > 0) {
        if(buf[rdsz - 1] == '\n') --rdsz;
        buf[rdsz] = 0;  /* add null-terminator */
        __android_log_write(ANDROID_LOG_DEBUG, tag, buf);
    }
    return 0;
}

這涉及編寫和/或修改程式碼。

有一種過時的方法可能仍然適用於舊版本 Android 的某些模擬器(我還沒有嘗試過),這在 Stack Overflow 上的一篇兄弟文章中進行了討論:https://stackoverflow.com/questions/10531050/redirect-stdout-to-logcat-in-android-ndk我認為在這裡嘗試重現該問答中的討論是不明智的,特別是因為選擇取決於該主題中討論的各種因素。一旦取得進展,請更新此主題。

相關內容