Android のコマンドライン アプリケーションのソフトウェア開発プロセスをさらに自動化したいと考えています。数年前なら、Busybox を物理的な Android デバイスにインストールし、顕微鏡を持ってきて、Emacs for Android で入力を始めていたでしょう。現在、私はもっと便利なコーディング方法を探しています。
特に、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;
}
これには、コードの作成および/または変更が含まれます。
古いバージョンの Android の一部のエミュレーターではまだ機能する可能性がある古いアプローチがあります (試していません)。これは Stack Overflow の関連記事で説明されています。https://stackoverflow.com/questions/10531050/redirect-stdout-to-logcat-in-android-ndkここでその Q&A の議論を再現しようとするのは賢明ではないと思います。特に、選択肢はそのトピックで議論されているさまざまな要因によって決まるからです。進展があったら、このトピックを更新してください。