android start-server
Java 内から外部プロセスとして実行しようとすると、さまざまな問題が発生します。Java は Gradle によって呼び出されます。さまざまなシナリオで正確に何が起こっているかを説明しましょう。
環境
- ウィンドウズ 7 X64
- Java 7
- commons-exec-1.1
- グラドル 1.6
- Android API 17
- IntelliJ IDEA 12.1.4 コミュニティ版
を呼び出すと adb デーモンが強制終了され、起動されると仮定adb start-server
します。
ケース1
このコード:
DefaultExecutor executor = new org.apache.commons.exec.DefaultExecutor();
executor.execute(org.apache.commons.exec.CommandLine.parse("adb start-server"));
log.info("Checkpoint!");
run
アプリケーション プラグインのGradle タスクから実行すると、次のような start-server 出力が表示されます。
* daemon not running. starting it now on port 5037 *
* daemon started successfully *
そしてハングします。つまり、「Checkpoint!」です。ログに記録されることはありません。プロセスadb.exe
を手動で強制終了すると、コードの実行が続行されます。
質問1
この呼び出しがブロックされる理由 コマンドが端末から実行されるとadb start-server
、数秒後に制御が端末に返されるのに、コードでそれが起こらないのはなぜですか?
ケース 2
代わりに、次のように Java ランタイムを直接使用する場合:
Runtime.getRuntime().exec(new String[]{"adb", "start-server"});
log.info("Checkpoint!");
System.exit(0);
以前のように Gradle から呼び出す場合、「Checkpoint!」記録されます。ただし、実行は保留されSystem.exit(0)
ます。手動adb.exe
で強制終了すると、再び Gradle 呼び出しが終了します。
この場合、 の出力adb start-server
は表示されません。
興味深いことに、Gradle の代わりに、Gradle のものを模倣したビルド設定で IntelliJ IDEA からアプリケーションを実行すると、すべてが正常に機能し、アプリケーションが正常に終了します。
質問2
Gradle がハングアップしSystem.exit(0)
、IntelliJ がハングアップしないのはなぜですか? これは、Gradle 自体が内部的に Java を呼び出すプロセスであり、IntelliJ の場合、Java が間接的に直接呼び出されるという事実と何らかの関係がありますか? なぜそれが重要なのですか?
質問 3
最終的には、これを Gradle からハングアップすることなく実行できるようにしたいと考えています。のログ出力はadb start-server
おまけです。これを行う方法のヒントをいただければ幸いです。