Как перенаправить stdout/stderr приложения Android с помощью ADB?

Как перенаправить stdout/stderr приложения Android с помощью ADB?

Я хочу автоматизировать большую часть процесса разработки программного обеспечения для некоторых приложений командной строки Android. Несколько лет назад я бы установил Busybox на физическое устройство Android, взял бы микроскоп и начал бы печатать в Emacs для Android. Сегодня я ищу более удобный способ кодирования.

В частности, я хочу перенаправить файловые дескрипторы stdout и stderr для приложений Android (NDK), подобно тому, как работает qemu-arm64-static.

Кто-нибудь знает, возможно ли это с ADB? В качестве альтернативы я мог бы структурировать свои приложения как микросервисы и использовать переадресацию портов ADB. Но при этом я бы потерял много классических соглашений UNIX.

Я вижу, что у ADB есть захват журналов для сообщений NDK (log.h) и SDK (Log.class). Но, к сожалению, я не вижу четкого способа перенаправить STDIN хоста в STDIN гостевого приложения Android.

Может быть, есть способ запустить Toybox (mksh) через adb и отправлять туда пользовательские команды sh?

решение1

Различные источники (напримерhttps://stackoverflow.com/a/36561699/340175иhttps://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Я не думаю, что разумно пытаться воспроизвести обсуждение из этого Q&A здесь, особенно потому, что выбор зависит от различных факторов, обсуждаемых в этой теме. Пожалуйста, обновите эту тему, как только вы достигнете прогресса.

Связанный контент