我想自動化一些 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/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我認為在這裡嘗試重現該問答中的討論是不明智的,特別是因為選擇取決於該主題中討論的各種因素。一旦取得進展,請更新此主題。