2013年1月27日日曜日

KyoroText で使用されている技術 その11




[課題] Terminalっぽいことを、してみたい。

私はxyzzyというEditorを愛用しています。xyzzyには、Editorからshellを操作する機能があります。
「KyoroTextにも、Shellモードが欲しいなぁ~」と考えていました。

ためしに実装してみたら、そこそこ動いたので簡単に紹介します。


[問題]
 Googleを多様して、以下のような問題を解決できました。
 -A Androidで、CLIアプリを動作させめ方法は?
 -B cd した後の、現在参照しているフォルダを利用したい?


[A] Androidで、CLIアプリを動作させる方法は?
 自分以外のAndroidアプリを起動する場合、通常は、Intentを使用します。
「cd」「ls」dateといった。/system/bin配下にあるネイティブアプリを動作させるには、
 どうすれば良いのでしょうか? Intentで実現できるのでしょうか?

 Runtimeクラス、ProcessBuilderクラスで実現できます。
 細かな使い方は、Google先生に聞くと良いでしょう。

 KyoroTextでは、以下のようなコードを書きました。
 https://github.com/kyorohiro/KyoroHelloAndroid/tree/master/KyoroCommon/src/info/kyorohiro/helloworld/util/shell
 CLIAppKicker

>
>   CLIAppKicker#start(String command)
>
startを呼ぶとCLIアプリを起動します。


 [B] cd した後の、現在参照しているフォルダを利用したい?

「Aの問題」が解決しました。なので、「ls」使いたい時は、「CLIAppKicker#start("ls")」
 とすれば、「ls」が呼べます。

 しかし、うまくいかない場合があります。
「cd」です。

 以下のようなシナリオを考えてみましょう。
  1. "/" にいる。
  2. cd mnt とする。
  3. cd sdcard
 として、SDカード配下に移動したいとする。

  1. CLIAppKicker#start("cd mnt")
  2. CLIAppKicker#start("cd sdcard")
 のようなコードで実現できそうです。しかし、
 子プロセスの情報は引き継がれません。

  1. CLIAppKicker#start("cd mnt")
  ---> /mntい移動する。
  2. CLIAppKicker#start("cd sdcard")
  --> /sdcardに移動する。
 となり、思い通りの場所(/mnt/sdcard)に移動できません。




 この問題は、CLIAppKicker#start("sh") とすることで解決できます。
 KyoroTextでは、以下のようなコードを書きました。
 https://github.com/kyorohiro/KyoroHelloAndroid/tree/master/KyoroCommon/src/info/kyorohiro/helloworld/util/shell
 CmdSession.java




[気をつけた点]
 topコマンドなど、プロセスが動作し続けるアプリでは、「InputStream#available() == 0」の状態で、InputStream#read()すると、次へ進まなくります。データが入力されるまで待機するためです。
なので、必ず、「InputStream#available() > 0」ことを確認してから、InputStream#read()する
ようにしました。



[次回]
テスト自動化はできた!!どのくらいテストできたか定量的に客観的にしりたい!!
どうすればよいでしょうか?
次回はEMMAというテストカバレッジツールを使用する方法について解説します。


0 件のコメント:

コメントを投稿