日々精進

新しく学んだことを書き留めていきます

android

CustomViewのlayout xmlにmergeタグを使うとレイアウトが崩れる問題

状況は以下 CustomView(名前はPositionView_)のlayout xmlのRootタグはmergeタグ <merge xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content" > ... </merge> Fragmen…

文字列をBigDecimalに変換する時に、変換出来ない場合nullにする

文字列をtry parseしてparse出来る場合だけBigDecimalに変換したいという場合。 NumberFormatExceptionをcatchして握りつぶせば良い。 try { rate.setDecimal(new BigDecimal(json.getJSONArray(2).getString(0))); } catch (NumberFormatException e) { // …

AndroidStudioのdebug windowのオブジェクト詳細について

debug windowのvariablesやwatchesには以下のようにオブジェクトが表示される。 jp.co.sample.common.NumberPicker{43becbd V.E..... ......I. 0,0-0,0 #7f09007f app:id/rate_number_picker} この例の43becbdはhashCode、#7f09007fはandroid:idの値。 16進…

Android Studioのビルドが途中で止まる

Android Studioをリスタートしても、マシンを再起動してもだめという場合は、メニューの File>Invalidate Caches / Restart...を選択し、Invalidate and Restartをクリックすると直るかも。 最近Android Studioのビルドが不安定で困る。。

「java.lang.NullPointerException: Attempt to write to field 'int android.support.v4.app.Fragment.mNextAnim' on a null object reference」エラー

原因は、fragmentをremoveすると、一瞬mFragmentManager.getFragments()で取得出来るListの要素にnullがある状態になるため。 以下のコードだとfragmentをaddしたりremoveしたりを繰り返すとNPEで落ちることがある。 for (Fragment fragment : mFragmentMana…

selectorリソースを使ってボタンの背景画像を切り替えられない

原因は、XMLファイル内の一番上にAttributeが付いていないitemを書いていたため。 selectorは上から順に評価されるので、常に一番上の画像を表示してしまっていた。 以下はだめな例。 <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/common_sell_radio_button"/> </item></selector>

@hideアノテーション付きメソッドはリフレクションを使うと呼び出せる

@hideアノテーションJavadocコメントに付いているメソッドは参照出来なくなるっぽい? 少なくともActivity#isResumedは呼び出そうとしてもビルドエラーになる。 が、リフレクションを使うと呼び出せる。そんな無理矢理アクセスしてたらSDKの内部実装が変わっ…

1,000のようなカンマつきの文字列をBigDecimalに変換する

DecimalFormatを使う。setParseBigDecimal(true)でparseメソッドがBigDecimalを返すようになる。 DecimalFormat decimalFormat = new DecimalFormat(); decimalFormat.setParseBigDecimal(true); BigDecimal d = (BigDecimal) decimalFormat.parse(string); …

Android Studioからビルドすると「Error:Android Gradle Build Target: org.gradle.tooling.GradleConnectionException: Could not execute build using Gradle installation」エラー

原因は謎だが、~/.gradleフォルダを削除してgradleを再インストールすると直った。 Android Studio不安定で困る。。 参考: Gradle error: could not execute build using gradle distribution

選択中のタブがクリックされたイベントを検知する

TabHostインスタンス生成時に以下を実行すればよい。 // hostはTabHost型のフィールド変数 TabWidget tabWidget = host.getTabWidget(); for (int i = 0; i < host.getTabWidget().getTabCount(); i++) { View tab = tabWidget.getChildAt(i); tab.setOnTouc…

SerializableとParcelableの使い分け基準

それぞれの特徴は以下。 Serializable Serializeロジックを自分で実装しなくて良いので楽。Serializeしたくないフィールドにはtransientを付ける。 Parcelable アプリ間でデータをやりとりすることができる ロジックを自分で書かないといけないので面倒。joh…

Robolectricのテストを実行すると「ERROR: transport error 202: connect failed: Connection refused」エラー

Debugではこのエラーが出るが、Runだと出ない サーバに接続できないとこのようなエラーが出るという報告が以下の記事であるが、サーバには接続できている Can't debugging JUnit + Roboloctric test in Android Studino with gradle gradlew buildを実行して…

HOME画面のアプリアイコンをタップして起動すると必ず起動画面に戻ってしまう現象

説明しづらいけど、現象は以下。 HOME画面のアイコンをタップしてアプリを起動する アプリ使用中にHOMEボタンをタップしてアプリをバックグラウンドに送る HOME画面のアイコンをタップして再度アプリをフォアグラウンドにする 起動画面が表示されてしまう(…

Androidでビルドすると「error: No resource identifier found for attribute 'maxValue' in package」エラー

原因はビルドの中間成果物が残っていたことだった。 ./gradlew cleanを実行したら直った。

AndroidAnnotationsとIcepickは一緒に使えない

理由は以下。 Icepickはビルド時にクラス名にsuffixを付ける。(classファイルの中を調べるとクラス名が変わっている) AndroidAnnotationsはサブクラスを生成する。そのクラスにはsuffixが付いていない。 IcepickはSuffixが付いているクラスのみRestore/Sav…

Dialogを下寄せで画面幅いっぱいに表示する

Dialogを表示すると通常は上下左右とも真ん中寄せになるが、下寄せで幅は画面いっぱいにしたい場合は以下のコードをDialogFragmentのサブクラスに実装すればよい。 @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityC…

potatotips#15発表資料(GradleTips)

potatotipsで発表してきます。 【第15回】potatotips(iOS/Android開発Tips共有会) (2015/03/12 19:00〜) 発表資料は以下。 http://hosokawa0825.github.io/slides/GradleTips/#/

adb, gradleコマンドを補完する

補完ライブラリの解説は以下参照。 Android開発を爆速にする10のコマンドラインスクリプト - クックパッド開発者ブログ adbの補完ライブラリはbash用のようだったが、↓によるとbash補完ライブラリはzshでも使えるらしい。 I have a bash-tab-completion scri…

APKの署名の設定をlocal.propertiesに書いてビルドする

下記サイトに書いてある通りにやるとできた。 http://wada811.blogspot.com/2014/10/avoid-exposing-signing-config-using-gradle-properties.html できたAPKがちゃんと署名されているかどうかはkeytoolとjarsignerを使うと調べることが出来る。 調べ方は以…

ライブラリのコードを変更し、動作確認するのを楽にする

gradleでライブラリをインストールした場合、ライブラリはコンパイル済みなのでコードを変更してアプリと一緒に動かしてみるということが気軽に出来ない。 ライブラリをアプリのプロジェクトからプロジェクト参照すればライブラリの修正・動作確認が非常に楽…

コードからViewインスタンスを生成する時にStyleを設定する

以下のコンストラクタの第三引数にスタイルを渡せばOK。 View(Context context, AttributeSet attrs, int defStyle) インスタンスを生成した後で変更することはできないっぽい。 参考: http://fujiiyuuki.blogspot.jp/2012/02/android-viewstyle.html

Android StudioのADB pluginが便利

ADB Ideaというpluginをインストールすると、いくつかのadbコマンドをAndroid Studioからワンアクションで実行できるようになり大変便利。 https://plugins.jetbrains.com/plugin/7380?pr=idea 使うのはほぼADB Uninstall Appだけだけど。。ADB Killを実行す…

アプリアイコンにGitのブランチ名、コミットハッシュ値などを表示する

以下のgradle pluginを使う。 splatte/gradle-android-appiconoverlay インストール手順は上記ページのUsageを参考にすればいいが、いくつか注意点が。 なお、確認した環境は以下。 OS X 10.9.5 gradle 2.2.1 以下注意点。 ImageMagickの他にGhostScriptもイ…

gradleでshell commandを実行する

gradleというかgroovyの機能。以下のようにしてshell commandを実行し、その結果を取得できる。 def proc = 'echo "test"'.execute() proc.waitFor() proc.in.text // 標準出力に出力された文字列を取得する 参考: Groovy - Executing External Processes F…

Dev, Staging等の各環境毎に異なるデータはbuildConfigFieldで指定する

下記記事でpro, freeなどのバージョン毎にリソースをまとめて定義する方法を書いたが、サーバのURLなどDev, Staging等の各環境毎に異なる値にしたいこともある。 2015-02-18 - 日々精進 そういう場合は、buildConfigFieldで指定し、BuildConfigクラスから取…

複数のProductFlavorでリソースを共有する

同じコードベースからpro版, free版を作成する場合などは以下のように6つProductFlavorを作ることが多い。 proDev, proStaging, proProduction, freeDev, freeStaging, freeProduction しかし、Dev,Stagingなどの環境毎にリソースを分けたくない。(文言など…

build variantの一部をビルド対象としない

product flavorを開発環境・テスト環境・本番環境などで分けることはよくあると思うが、 その場合開発環境・テスト環境版はreleaseビルドさせたくないだろう。 そういう場合にbuild variantの一部をビルド対象としないようにするにはvariantFilterを使う。 a…

androidannotationsを使っているプロジェクトでproductFlavorsを追加するとビルドエラーになる

環境: apt plugin: 'com.neenbedankt.gradle.plugins:android-apt:1.4' gradle version:2.2.1 androidannotationsを使っているプロジェクトでproductFlavorsを追加すると':app:proDebugTestCompile' taskが失敗した旨のエラーメッセージが出た。 resourcePa…

mergeタグを使うとdesign viewでviewが崩れる問題

今のところ、design viewを表示するときはmergeタグをLinearLayoutなどに変更するしかなさそう。 ググって解決策がいくつか書いてあるサイトを見つけたが、どれもイマイチだった。 http://gotoanswer.stanford.edu/?q=Preview+layout+with+merge+root+tag+in…

TabHostの高さを設定する

以下のように設定する。 for (int i = 0; i < host.getTabWidget().getTabCount(); i++) { host.getTabWidget().getChildAt(i).getLayoutParams().height = getResources().getDimensionPixelSize(R.dimen.tab_bar_height); } 参考: How to resize the heig…

ビルドが成功しているのにsupport libraryに入っているクラス・メソッドが赤文字になっている現象

Android Studio1.1.0を使っているが、ちょくちょくビルドが成功しているのにsupport libraryに入っているクラス・メソッドが赤文字になっている現象が発生する。 そんな時は以下で直る。 赤字になっているところでAlt+Enterを押すとsupport libraryへのclass…

「最新事例から学ぶ!モバイル向けテスト手法勉強会」で発表してきます

以下の勉強会で発表してきます。 【iOS/Android】最新事例から学ぶ!モバイル向けテスト手法勉強会 (2015/02/28 14:30〜) 発表資料: http://hosokawa0825.github.io/slides/RobolectricPitfalls/#/

Androidのmatryoshka problem(Fragmentが入れ子になると起こる不具合)

matryoshka problemについて詳しく書いているサイトがあったのでメモ。 Android's matryoshka problem だいぶやばいバグだな。。最近FragmentManagerとFragmentTransactionに悩まされてるしFragmentつらい。

テスト用FixtureをYAMLで書くか、JSONで書くか

テストデータをテストコードに直書きするのがつらい場合があるので、 なんらかのフォーマットで別ファイルに切り出すことにした。 YAMLにするかJSONにするかで迷ったが、JSONにした。主な理由は以下。 サーバとのやりとりにJSONを使っているので統一したかっ…

ActivityNotFoundException No Activity found to handle Intentエラー

原因はIntentで指定したaction/URI Schemeを解釈するアプリが無いため。 エミュレータで動かしていたのでGooglePlayアプリが入っていないことが直接の原因だった。 実機で動かしたら正しく動いた。 参考: No Activity found to handle Intent : android.int…

Androidの実機をPCに繋いだが認識されない

具体的にはRunした時に出てくるChoose Deviceウィンドウに繋いだ実機が表示されなくて困った。 直し方は以下。 ターミナルからadb devicesを実行する。デバイスが出てこなかったらadbが認識できてない。 USBコネクタを一旦抜いてまた挿してみる。ダメなら次…

基本的に実行時例外を使うようにするという方針

Javaは例外を無視できないよう、メソッド定義のthrows句でthrowする例外を指定する。 メソッドをの呼び出し側もこれを意識してcatchするなりthrows句に例外を指定するなりしないといけない。 これによって静的なチェックが可能になり、アプリが堅牢になる、…

オブジェクトがあるクラスのインスタンスであることを完全一致で判定する

obj instanceOf Klassだと、KlassのサブタイプでもOKだが厳密にKlassのインスタンスであることを判定したい場合は obj.getClass() == Klass.classとする。 参考: Javaのinstanceof演算子 - とあるソフトウェア開発者のブログ

TabHostのTabに表示される文字サイズを変更する

カスタムThemeを定義し、それをActivityのThemeにすればよい。 詳細は下記サイトの例参照。 How to change the font size of tabhost in android

ZipEntry#getSize()が-1を返す

sizeがunknownな場合に-1を返す仕様らしい。 zipファイルをmacで作ると-1を返すようになり、Windowsで作ると正しいサイズをとれるようになった。 うーん、なぜだ。 参考: Inconsistency between ZipEntry size for ZipInputStream and JarInputStream

ResourceIdからResourceNameを取得する

Contextの以下のメソッドを使うと取得できる。 getResources().getResourceEntryName(int resid); // または以下 getResources().getResourceName(int resid); 参考: How to get Resource Name from Resource id

RobolectricでExecutorServiceを使った非同期処理のテストを行う

またRobolectricのつらみ記事です。 非同期処理のテストを行う場合、Robolectric.runBackgroundTasks();を使ってBackgroundTaskを実行するが、ExecutorServiceを使って非同期にしている場合はrunBackgroundTasksが効かなかった。 ExecutorServiceのShadowと…

Robolectricでテスト実行時にassetsフォルダ・resourcesフォルダを複数設定する

こんなのよくやることだと思うのに、dirty hackな方法しか見つからなかった。。 もっとまっとうな方法はないんだろうか? RobolectricTestRunnerのサブクラス(MyTestRunner)を作る。 MyTestRunnerに以下を実装してassets/resourcesフォルダを追加する @Overr…

Mockitoで戻り値がvoidのメソッドをMockする

spyでやる場合は以下のように書く。 target = Mockito.spy(new MyClass(Robolectric.application)); // targetのcheckメソッドをMockにする。引数に何を渡されたときでもMockにしたい場合は // Mocito.<引数の型>any()を渡す。 doNothing().when(target).che…

Robolectricでテスト実行開始時に一度だけ処理を実行させる

Robolectricで単体テスト実行中にBuild.VERSION.RELEASEからOSのバージョンを取得すると、"unknown"が返ってくる。 これでは都合が悪いので、テスト実行開始時にBuild.VERSION.RELEASEを書き換えてやろうと思ったのが事の発端。これが結構大変だった。。 や…

potatotips#14発表資料(主にAndroid StudioのTips)

potatotips#14に行ってきます。発表資料は以下。 発表資料 もう14回もやってるんだねぇ。すごい。

Androidのレイアウトを作るときは横幅320dpと384dpでチェックすべき

Nexus Oneでアプリを表示するとレイアウトが崩れて悲しい思いをしたのでどうレイアウトを作ればいいか調べた。 dp単位でも端末によって横幅は多少違いが出るらしい。が、320~384に収まっているのでこの両端でチェックすればOKであろうという結論になった。 …

InstanceStateのsave, restoreを簡単に書けるIcepickが便利

使い方は下記記事参照。これでInstanceStateの取り扱いのダルさがかなり軽減されそう。 Android の罠 [1] ちゃんと onSaveInstanceState する - Qiita てかアプリの状態の復元ぐらいラインタイムの方でやってよ。。 フィールド変数が突然消えないiOSは幸せだ…

GenymotionのVMをコマンドラインから起動する

いずれalfred workflowを使って起動できるようにしたい。 手でやる場合の手順は以下。 VBoxManage list vmsでVMのリストを取得する /Applications/Genymotion.app/Contents/MacOS/player --vm-name ""でVMを起動する 手でやるんだったらGUIからやるわって感…

maven centralに登録されているライブラリを楽にbuild.gradleに追加する

Cmd+;でProject Structureを開き、Dependenciesタブを開き、+ボタンをクリックして表示されるウィンドウでmaven centralに登録されているライブラリを検索できる。 butterで検索しても何も表示されなかったが、butterknifeで検索したらヒットした。部分一致…