일부 Android 명령줄 애플리케이션에 대한 소프트웨어 개발 프로세스를 더 많이 자동화하고 싶습니다. 몇 년 전이었다면 실제 Android 기기에 Busybox를 설치하고 현미경을 가져와서 Android용 Emacs에 타이핑을 시작했을 것입니다. 오늘은 좀 더 편리한 코딩 방법을 찾아보겠습니다.
특히 qemu-arm64-static 작동 방식과 유사하게 Android(NDK) 애플리케이션용 stdout 및 stderr 파일 설명자를 리디렉션하고 싶습니다.
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;
}
여기에는 코드 작성 및/또는 수정이 포함됩니다.
Stack Overflow의 형제 기사에서 논의된 이전 Android 버전의 일부 에뮬레이터에서는 여전히 작동할 수 있는 오래된 접근 방식이 있습니다(시도해 본 적은 없습니다).https://stackoverflow.com/questions/10531050/redirect-stdout-to-logcat-in-android-ndk특히 선택은 해당 주제에서 논의된 다양한 요소에 따라 달라지기 때문에 여기서 Q&A의 토론을 재현하려고 시도하는 것은 합리적이지 않다고 생각합니다. 진행이 완료되면 이 주제를 업데이트하세요.