2012年1月22日日曜日

今更ながらAntでAndroidのTestを実行してみる

前回初めてAnt触ったわけですが、とりあえず気になったんでやって見ました系

Ant詳しくない俺がやっているので間違っていたらツッコミください。
この辺とか参考


例によってEclipseから適当にプロジェクトを生成。
その時Testプロジェクトも作成

HelloAnt/
├── AndroidManifest.xml
├── assets
├── bin
├── gen
├── proguard.cfg
├── project.properties
├── res
└── src
    └── jp
        └── omokageru
            └── dnk
                └── helloant
                    └── HelloAntActivity.java

HelloAntTest/
├── AndroidManifest.xml
├── assets
├── bin
├── gen
├── proguard.cfg
├── project.properties
├── res
└── src
    └── jp
        └── omokageru
            └── dnk
                └── helloant
                    ├── HelloAntActivityTest.java //これは自分で作る
                    └── test

//HelloAntActivityTest.java
package jp.omokageru.dnk.helloant;

import android.test.ActivityInstrumentationTestCase2;

public class HelloAntActivityTest extends ActivityInstrumentationTestCase2<HelloAntActivity> {

    public HelloAntActivityTest() {
        super("jp.omokageru.dnk.helloant", HelloAntActivity.class);
        // TODO Auto-generated constructor stub
    }

    public void testText() throws Exception {
        assertEquals("Hello World, HelloAntActivity!",
                getActivity().getString(jp.omokageru.dnk.helloant.R.string.hello));
    }
}

HelloAntとTestの親ディレクトリへ居るとしてAntプロジェクト用にupdate

2012/01/25 修正
http://developer.android.com/guide/developing/testing/testing_otheride.html#UpdateTestProject にある通り、「android update test-project」を使うべきでした。
update test-projectで引数に指定したとおりant.propertiesが生成されます。

android update project -p HelloAnt/
# android update project -p HelloAntTest/ 
# test-projectの-mは -pからみた相対パスか絶対パスを指定する
android update test-project -m ../HelloAnt/ -p HelloAntTest/

そしてTest側にant.propertiesファイルを作成します。
中身はこんな感じ
# HelloAntとHelloAntTestが並列なのでこんな感じ
# tested.project.dir=../HelloAnt/
# test-updateにより自動で生成される


あとはエミュレータか、端末がつながっている状態で下記のように実行するとこんな感じです。
# HelloAntTestディレクトリに居るつもり
ant all clean debug install test
# 出力中略
-test-project-check:

test:
     [echo] Running tests ...
     [exec] 
     [exec] jp.omokageru.dnk.helloant.HelloAntActivityTest:
     [exec] .
     [exec] Test results for InstrumentationTestRunner=.
     [exec] Time: 0.315
     [exec] 
     [exec] OK (1 test)
     [exec] 
     [exec] 

BUILD SUCCESSFUL
Total time: 13 seconds

まあ all cleanが居るかどうかはびみょーなところでしょうけど無くて困るものでもないし…



試しに ant emma debug install test
とか叩いて見ましたが怒られました。
WARNING: Code Coverage is currently only supported on the emulator and rooted devices.
だそうです…

エミュレータ上でとりあえず試してみたらこんな感じでした。


root端末上でやるならばこの辺参考にすれば出来るんでしょうけど、
誰かやってないのかなぁ…(日本語でのまとめ的な意味で)



Embedded tweets の使い方がようやく分かった…?

簡単に言うとこれの使い方が知りたかったのです。



なんでも「Blackbird Pie」というものがあったらしいのですが、これがなくなって「Embedded tweets
というものになったらしい…

で、どうも「Embed this tweet」みたいなのがリンクとして追加されているっぽい。
それを叩くとダイアログが出てきて…

とかだと思うんですが…

無いよね…どう見ても…







※俺の理解力がない可能性は否定しない




まあでもAPI叩けばJSONが返ってきて、その結果をそのまま使って貼りつければOKっぽいので
それっぽいものを作った段階で気がついた


この形だけ書いてhref部分のみ書き換えれば、「widgets.js」が勝手に理解してゴニョゴニョしてくれることを…
注意点としてはpタグの間はスペースでも何でもいいからとりあえず「何か入っていないと駄目」っぽい

先にこっちを見つけておけば…

ということで有意義な27歳最後の日の午前でした。



ぽいものを作った跡地

そんなに叩いたつもり無いのにAPI制限引っかかってしましました…
んー、うちの環境がマンションだからか?
→建物レベルでIP一緒

いちおー動いてたんですけど、だれか動作確認…なんかしなくていいです。



2012年1月15日日曜日

qguardを使ってみた #TokyoMercurial の感想込

TokyoMercurialへ行って来ました。

内容は意外なことに、個々でモクモク。
たまに来る質問に対して盛り上がる系でした。

@modal_soulさんによるTweetのまとめはこちら
#TokyoMercurial #1 まとめ その1
#TokyoMercurial #1 まとめ その2

次回は2/25

感想
変態や神の多い勉強会で楽しかったw




そんな質問->盛り上がるのなかで「qguard」という単語が出てきました。
知らなかったので使ってみた。

てかそもそもqguardってなんやねん。

$ hg -v help qguard
hg qguard [-l] [-n] [PATCH] [-- [+GUARD]... [-GUARD]...]

パッチのガード設定ないし表示

    「ガード」はパッチ適用の可否を制御します。 ガードが設定されていない
    パッチは常に適用されます。 「正」のガード(例: "+foo")が設定された
    パッチは、 "hg qselect" によって当該ガードが設定されている場合に限り
    適用されます。 「負」のガード(例: "-foo")が設定されているパッチは、 "hg
    qselect" によって当該ガードが設定されている場合は適用されません。

    引数指定が無い場合、 現在のガード選択状況を表示します。
    引数が指定された場合、 指定パッチに対するガード選択を設定します。

    備考:
       「負」のガード設定には、 ガード指定の前に '--' 指定が必要です。

    現行パッチ以外にガードを設定するには:

      hg qguard 対象パッチ名 -- +2.6.17 -stable

    成功時のコマンド終了値は 0 です。

らしい。

とりあえず試してみる。

@  チェンジセット:   3:f8c4733a0105
|  タグ:             tip
|  ユーザ:           dnk
|  日付:             Sat Jan 14 22:57:24 2012 +0900
|  要約:             4th
|
o  チェンジセット:   2:38ad6ad44a14
|  ユーザ:           dnk
|  日付:             Sat Jan 14 22:56:26 2012 +0900
|  要約:             third
|
o  チェンジセット:   1:22ff7bf5abb1
|  ユーザ:           dnk
|  日付:             Sat Jan 14 22:55:21 2012 +0900
|  要約:             second
|
o  チェンジセット:   0:bbd7202921cd
   ユーザ:           dnk
   日付:             Sat Jan 14 22:54:47 2012 +0900
   要約:             first
とりあえずこんな感じのものを用意。
上記の状態の準備すらメンドイ人向けに https://bitbucket.org/daneko/qguardtest1 に配置しました

一旦全部パッチ化

$ hg qimport -r 1 -r 2 -r 3
$ hg qguard -l
1.diff: unguarded
2.diff: unguarded
3.diff: unguarded

1,2にマイナスのガードを追加
これ個別にしか指定できないのかなぁ…

$ hg qguard 1.diff -- -hoge
$ hg qguard 2.diff -- -hoge
$ hg qguard -l
1.diff: -hoge
2.diff: -hoge
3.diff: unguarded
$ hg qpop -a

$ hg qselect hoge //ガードを選択
ガード設定の変更により、 適用除外パッチ数が 3 から 1 になりました

$ hg qpush -a
3.diff を適用中
適用中の最上位パッチは 3.diff です
$ hg glog
@  チェンジセット:   1:45ac9d559036
|  タグ:             3.diff
|  タグ:             qbase
|  タグ:             qtip
|  タグ:             tip
|  ユーザ:           dnk
|  日付:             Sat Jan 14 22:57:24 2012 +0900
|  要約:             4th
|
o  チェンジセット:   0:bbd7202921cd
   タグ:             qparent
   ユーザ:           dnk
   日付:             Sat Jan 14 22:54:47 2012 +0900
   要約:             first

素晴らしい!

とりあえず元に戻しましょう。

$ hg qselect -n // guard を外す
$ hg qpop // 3.diffだけ設定されているので一度外す
$ hg qpush -a

次はプラス側のガードを試してみる

$ hg qguard 1.diff +hoge
$ hg qguard 2.diff +hoge
$ hg qguard 3.diff +huga
$ hg qguard -l
1.diff: +hoge
2.diff: +hoge
3.diff: +huga
$ hg qselect hoge
$ hg qpush -a
1.diff を適用中
2.diff を適用中
3.diff を抑止 - ガード '+huga' が適用されました
適用中の最上位パッチは 2.diff です

上手に使えばseriesファイルを直接弄っていたあんなシチュエーションやこんなシチュエーションが減りそうです(ぇ


qguardが出てきたのは下記のような話題が出たからでした。

A->B
とコミットしてしまったが
A->C->B
とすべきだった(したほうが後々見直す上でよかった)ときにどうするか?
ここでCはA->Bの中間生成物的なものとする
recordはちょっと使えないというシチュエーション


あくまで下記は俺が覚えている(というかうろ覚え)範囲なので、間違っているかもしれないし
当然他の方法だっていっぱいあると思います。

とりあえずその記憶を下記にメモ

$ hg glog
@  チェンジセット:   1:9cd39df9c615
|  タグ:             tip
|  ユーザ:           dnk
|  日付:             Sun Jan 15 00:01:38 2012 +0900
|  要約:             second
|
o  チェンジセット:   0:1e8e287648f5
   ユーザ:           dnk
   日付:             Sat Jan 14 23:59:47 2012 +0900
   要約:             first

まず状態Cを手動で作る
(現状の状態から必要なだけ削ってコミット)

$ hg glog
@  チェンジセット:   2:8ee095d38d45
|  タグ:             tip
|  ユーザ:           dnk
|  日付:             Sun Jan 15 00:12:35 2012 +0900
|  要約:             third
|
o  チェンジセット:   1:9cd39df9c615
|  ユーザ:           dnk
|  日付:             Sun Jan 15 00:01:38 2012 +0900
|  要約:             second
|
o  チェンジセット:   0:1e8e287648f5
   ユーザ:           dnk
   日付:             Sat Jan 14 23:59:47 2012 +0900
   要約:             first

というわけで
A->C->Bを作る前に
A->B->Cを作ったということになります。

上記の状態の準備すらメンドイ人向けに https://bitbucket.org/daneko/qguardtest2 に配置しました


$ hg qimport -r 1 -r 2 // CとBをパッチ化
$ hg diff -r 0 -r 2 > X.diff // A->Cの差分作成
$ hg diff -r 2 -r 1 > Y.diff // C->Bの差分作成
$ hg qimport X.diff Y.diff  // 追加
$ hg qpop -a
2.diff の適用解除
1.diff の適用解除
全てのパッチの適用が解除されました

$ hg qguard 1.diff -- -hoge
$ hg qguard 2.diff -- -hoge
$ hg qselect hoge
ガード設定の変更により、 適用除外パッチ数が 4 から 2 になりました
$ hg qpush -a
X.diff を適用中
Y.diff を適用中
適用中の最上位パッチは Y.diff です


あとはパッチをリビジョン化すればOK
1.diff 2.diff の削除も同時にやればおしまいというところでしょうか?



さて次回に向けて勉強しないと白い目で見られそうです
mercurialのソース少し読んで見ることにします(白目



2012年1月14日土曜日

今更ながらAntでAndroidアプリをビルドしてみる

件名の通り、今更ながらAntでビルドして見ました。
AntでAndroidをビルドしたことない人向けです。つまり俺。

AndroidSDKやらADTはver16です。

流れ
・とりあえずビルドする(デバッグビルド)
・リリースビルドで署名まで済ませる
・NDKでのビルドも含める

このあたり参照
http://developer.android.com/guide/developing/building/building-cmdline.html

流石にAntやJDKはインストール済みでパスが通っていることは前提


とりあえずデバッグビルド


とりあえず既にあるeclipseのプロジェクトと共存することが前提なので、
対象プロジェクトはeclipseで作ります。
ここではHelloAntという名前で作った前提となっています。

そうするとこんなディレクトリ構成かと

HelloAnt
├── AndroidManifest.xml
├── assets
├── bin
├── gen
├── proguard.cfg
├── project.properties
├── res
└── src

とりあえず上記HelloAntディレクトリに移動
で、以下コマンドを実行

android update project -p ./

すると以下の結果となる

Updated local.properties
No project name specified, using Activity name 'HelloAntActivity'.
If you wish to change it, edit the first line of build.xml.
Added file ./build.xml
Updated file ./proguard.cfg

build.xmlとlocal.propertiesという2つのファイルが増えているはず

HelloAnt
├── AndroidManifest.xml
├── assets
├── bin
├── build.xml
├── gen
├── libs
├── local.properties
├── proguard.cfg
├── project.properties
├── res
└── src

これでAntプロジェクトとして作成されました。


おもむろに以下コマンドを叩きます

ant debug

binディレクトリに行くと「HelloAntActivity-debug.apk」として出来ているはず。

以上でデバッグビルドは終わり。


リリースビルドに署名まで済ませる


まずkeystoreを作成する(略)

次に「ant.properties」というファイルを作成し以下の内容を書く
key.store=hoge.keystore //(へのパス)
key.store.password=hogehoge
key.alias=hoge
key.alias.password=hugahuga

key.storeの右辺にはkeystoreファイルのパスを記載すればOK
ここではhoge.keystoreという名前でHelloAntディレクトリ直下に居る前提なので
単に「hoge.keystore」と書かれています。

HelloAnt
├── AndroidManifest.xml
├── ant.properties
├── assets
├── build.xml
├── hoge.keystore
├── libs
├── local.properties
├── proguard.cfg
├── project.properties
├── res
└── src

おもむろに以下コマンドを叩く

ant release

binディレクトリに行くと「HelloAntActivity-release.apk」として出来ているはず。

以上でリリースビルドは終わり。


一旦キレイにする


ant clean

binとかgenディレクトリが消えるよ!


proguardを使う


通常eclipseで使うのと一緒
project.propertiesに以下の一行を追加

proguard.config=proguard.cfg //(へのパス)

昔はantでproguardは大変だったらしい。

追加で記入したら「ant release」でprogurardがapkに使われます。


NDKでのビルドも含める


ndkにもパスが通っていることが前提です。

ついにbuild.xmlを開きます。
そして51行目付近を見ます



上記部分をこんな感じに書き換えます

    
        
            
            
        
    


これで実行!と言いたいのですが、そもそもNDKのソースが無いのでsampleの「hello-jni」から
jniディレクトリごとコピーしてきます。

HelloAnt
├── AndroidManifest.xml
├── ant.properties
├── assets
├── build.xml
├── hoge.keystore
├── jni
│   ├── Android.mk
│   └── hello-jni.c
├── libs
├── local.properties
├── proguard.cfg
├── project.properties
├── res
└── src
hello-jni.cの関数名修正を忘れずに。
あと呼び出し元も無いので適当に作ってください。

めんどければhello-jniごとコピーで、antプロジェクト作成でもOKです。

ant release/debug
と叩けば-pre-buildの項目がこんな感じで出力されます

-pre-build:
     [exec] Compile thumb  : hello-jni <= hello-jni.c
     [exec] SharedLibrary  : libhello-jni.so
     [exec] Install        : libhello-jni.so => libs/armeabi/libhello-jni.so



NDKでのビルドも含める その2


NDKだけ常にリリースビルドじゃ芸がないのでさっき修正した場所を下記のようにして見ました。

    
        
            
        
    

    
        
            
                rel!
                
                    
                    
                
            
            
                dev!
                
                    
                    
                
            
        
    

これでdebug指定時はNDK_DEBUG=1でビルドされます。

なお、ant releaseなのかdebugなのかは
android-sdk/tools/ant/build.xml
を見て、${build.target}に直接文字列入れていたのでそれで判定しましたが…
いいのかな…

あとはコンパイル失敗をsoファイルができたかどうかとかでチェックしてやればより良いかも?

そういやndk-buildをオプション無しで叩いてもリリースビルドでチョットびっくり。
r4ぐらいの時、デフォルトはデバッグビルドじゃなかったでしたっけ?


おまけ


ant clean
ant release -v > tmp.txt
で詳細をよく見てみたら…

-compile:
Property "tested.project.absolute.dir" has not been set
Property "tested.project.absolute.dir" has not been set
    [javac] jp/omokageru/dnk/helloant/HelloAntActivity.java added as jp/omokageru/dnk/helloant/HelloAntActivity.class doesn't exist.
    [javac] /Users/dnk/personal/android/HelloAnt/gen/R.java.d skipped - don't know how to handle it
    [javac] jp/omokageru/dnk/helloant/R.java added as jp/omokageru/dnk/helloant/R.class doesn't exist.
    [javac] Compiling 2 source files to /Users/dnk/personal/android/HelloAnt/bin/classes
    [javac] Using modern compiler
    [javac] Compilation arguments:
    [javac] '-d'
    [javac] '/Users/dnk/personal/android/HelloAnt/bin/classes'
    [javac] '-classpath'
    [javac] '/Users/dnk/personal/android/HelloAnt/bin/classes:/Users/dnk/personal/android/HelloAnt'
    [javac] '-sourcepath'
    [javac] '/Users/dnk/personal/android/HelloAnt/src:/Users/dnk/personal/android/HelloAnt/gen'
    [javac] '-target'
    [javac] '1.5'
    [javac] '-bootclasspath'
    [javac] '/Users/dnk/app/android-sdk/platforms/android-8/android.jar'
    [javac] '-encoding'
    [javac] 'UTF-8'
    [javac] '-g'
    [javac] '-source'
    [javac] '1.5'


ん?1.5?
確か今ってビルドの指定は1.6じゃなかったでしたっけ?

ということで
android-sdk/tools/ant/build.xmlで、1.5指定のところ2ヶ所を1.6に書き換えて動作させて見ましたが、
問題なく動いているきがしました。

ant testとかあるけど、そのへんはきっとtest部の方々が総掛かりでまとめてくれることを勝手に期待しております。


リリースが頻発するとか、NDKを含めたコンパイルが多いとかだとAntの方が楽?
普段のデバッグビルド状態だとEclipseが吐き出したもので困ることはありませんが、
準備しておけば楽っぽいですね。

あと、複数人で開発しててちゃんとビルドサーバっつーかCIサーバみたいなのが有るところだと必須なんでしょう。

そういうところだとどんなAndroid開発なのか凄く気になる…



2012年1月6日金曜日

【未解決】 BOOT_COMPLETEDとamコマンド

起動のイベントを取るには以下をBroadcastReceiverで受ければOK

android.intent.action.BOOT_COMPLETED

詳細は例によってtechboosterさんとかを参照
http://techbooster.org/android/application/1100/

これらの動作を確認するのに一々rebootなんかしてられませんので、
下記コマンドをターミナルから叩いて動作確認!

adb shell am broadcast -a android.intent.action.BOOT_COMPLETED

と思ったらこれが受信しないわけです。

結論から言うとパーミッションをマニフェストに書く位置が問題でした。


以下だとOK





    

    
        
            

            
        
    



以下だと「実際に端末を起動」したときはOKですが、ターミナルからイベント発行時はなぜか認識されず…
認識しなかった端末は以下
  • Desire
  • INFOBAR
  • IS03





    

    
        
            

            
        
    




    

    
        
            

            
        
    


これ何故なんでしょうか…

ちなみにエミュレータだとどれでも問題なく動作します。

なお後者の書き方でイベント発行時はこんな警告が出ます

permission denial言われてもねぇ…
そしてプリインストールと思われるアプリも幾つか引っかかっている。

とにかくBOOT_COMPLETEDをターミナルから叩くときは、端末によってはパーミッション書く位置で
動作しなかったりするっぽいから注意!でいいのだろうか?

もしくは他に要因があるのかな?詳しく知っている人居たら教えて欲しいです。

2012年1月1日日曜日

GAE for Pythonをちょっとだけ触ってみた

あけましておめでとうございます。
正月からやること無い大晦日からちょこちょこ触った結果を記録に…

対象はこんな感じ
  • Pythonの文法くらいはわかっている(要は俺)
  • Google主催の勉強会行く度にAppEngine触ってなくて肩身狭い気がする(要は俺)
  • 正月なのにコーディング以外やること無い(要はお…)
  • AptanaとかでGAEのPython2.7やりたい


環境はこんな感じ


まあAptanaでもEclipseにAptanaPluginでもいいんですけどね。
エディタでもいいんですけど、俺みたいなゆとりプログラマはIDEじゃないと…



Aptanaを適当に立ち上げ、File→New→OtherでAppEngineを選ぶ

プロジェクト名に適当な(ここではhelloworld)名前を入力し、次へを押すとこうなる

とりあえずBrowseを押してみるとdev_appserver.pyとかがあるディレクトリ指定しろとある。


でまあこれMacだと多分以下ディレクトリを指定するんですが…このエクスプローラーから選択する方法がわかりません(ぇ
下記ディレクトリを直接指定します。

/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/

すると以下のような画面になるので、チェックを入れてOKを押下


そうするとこうなるのでnextを押下



そしてとりあえずEmpty Projectを選択

あとはスタートガイドに沿って…



残念ながら今回の目的の2.7は日本語での情報はありません…
とはいうものの暫くはサクサク進むかと。



きっとUsing Templatesまではさくっと進みます。
いざUsing Templatesまで進むと

2.5の時はDjangoだったのに、時代は変わったんですね。ホムホム
とかなんとか考えて入力するとこうなる。


補完を信じると
import jinja2
にならない…

まあ単純にjinja2インストールしてない、していてもプロジェクトにパス通ってないからなんですけどね。
(2.5の時はサンプルがDjangoなんですが、インストールした記憶無いけど動いてた記憶が…)

ちなみにwebapp2_extrasのjinja2をImportしても、中ではjinja2呼んでいるので、Using Templateの項目の
jinja_environment = jinja2.Environment(
    loader=jinja2.FileSystemLoader(os.path.dirname(__file__)))
のEnvironmentが見つかんねーよって言われます。


という訳でjinja2をInstallしていない人はinstall
詳細はこちらとか
私はeasy_installにてインストールしました

そしてApatan側でもそのパスを通します。多分この辺に居る筈です。
/Library/Python/2.7/site-packages/Jinja2-2.6-py2.7.egg

プロジェクトのプロパティからjinja2のパスを追加してあげるだけ。



これでめでたく補完が効きます。



あとは動かしてみるとこんな感じ。
localでもちゃんと動く



とか思っていたら、こんなログ出てた
ERROR    2012-01-01 04:43:59,290 dev_appserver_import_hook.py:1319] Third party package markupsafe was enabled in app.yaml but not found on import. You may have to download and install it.

こちらのjinja2翻訳サイトによると、Markupsafeでより高速になるっぽい。
まあ無くても実害はなさそうですが…一応入れてみる。
でもError扱いはなんか違うんじゃ…

まずMarkupsafeをDLしてきて、解凍。
あとは python setup.py install で終わり。

再度動作させてみると、ログも綺麗に。


faviconが無いのはまあいいでしょ…

ということで今年は去年よりもいっぱいpython触りたいと思います〜