我想让一些 Android 命令行应用程序的软件开发过程更加自动化。几年前,我会在实体 Android 设备上安装 Busybox,拿来显微镜,然后开始在 Emacs for Android 中输入代码。如今,我正在寻找一种更方便的编码方式。
具体来说,我想重定向 Android(NDK)应用程序的 stdout 和 stderr 文件描述符,类似于 qemu-arm64-static 的工作方式。
有人知道这是否可以通过 ADB 实现吗?作为替代方案,我可以将我的应用程序构建为微服务并使用 ADB 端口转发。但这样做会失去很多经典的 UNIX 惯例。
我看到 ADB 具有日志捕获功能,可用于 NDK (log.h) 和 SDK (Log.class) 消息。但遗憾的是,我没有找到将主机 STDIN 重定向到 Android 客户机应用程序 STDIN 的明确方法。
也许有一种方法可以通过 adb 触发 Toybox(mksh)并在那里发送自定义 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我认为尝试在此重现该问答中的讨论是不明智的,特别是因为选择取决于该主题中讨论的各种因素。一旦取得进展,请更新此主题。