FirebaseCrashReportingにmappingファイルをあげるスクリプトを作った
FirebaseCrashReportingにAndroidのマッピングファイルをあげる際に相対パスが使えなかったり、google-services.jsonがapp直下にない時にAppIdなどを指定するのが面倒くさかったのでgolangでスクリプトを作ってみました
ソースコードは https://github.com/sckm/fcr-upload-mapping
動作環境
- あらかじめgoがインストールされている必要があります
- Mac OS X El Capitan以外では動作を確認していないです
- 内部でfirebase-crashプラグインで生成されるコマンドを使っているのでプラグインを適用する必要があります(バージョン1.0.5以上)
Uploading ProGuard mapping files with Gradle
インストール
go get github.com/sckm/fcr-upload-mapping
使い方
cd [Androidプロジェクトのルートパス] fcr-upload-mapping \ -a [サービスアカウントキーファイルのパス] \ -c [アプリバージョンコード] \ -p [パッケージ名] \ -m [マッピングファイルのパス] \ -s [google-services.jsonのパス]
google-services.jsonがapp直下にある場合は省略可能です
その他
今はgradlewがあるディレクトリでしか動かないようになっていたり、引数の説明が足りないので修正したい
Golangに慣れていないのでコードが汚い・・・
RxJava2のSingle.zipのエラー処理ではまった話
問題
RxJavaでたまにonErrorReturnItem
などでエラー処理をしていてもたまにエラーがすり抜けてきてアプリが落ちてしまうことがあった
問題となっていそうな部分を簡単に表すと以下のようになっていた
Single.zip( Single Single ) .onErrorReturnItem
対処方法
RxJavaのissuesを調べてみると同じ問題があった
Rx2: Multiple errors in zip'ed observables throw exception
ここに書いてある対処方法は、
RxJavaPlugins.setErrorHandler()
でエラーハンドラーを設定する(issueのコメントではsetOnError
になっているが名前が変更になった?)- zipの中のSingleで
onErrorReturn
やonErrorResumeNext
などを呼び出す
いっけん良さそうに見えるので原因がわかりづらくてはまってしまった
実際にはどうしてそうなってしまうのかまだわかっていないのでRxJavaの実装を読んでいきたい
文字列リソースに複数の値を渡す
基本的な方法
複数の値を渡す際には%1$s
や%2$s
などを設定する。
1や2で何番目の引数を使うかを指定する
<string name="string_res1">1番目%1$s 2番目%2$s"</string>
getString(R.string.string_res1, "A", "B") 結果: 1番目A 2番目B
渡した値の一部を使わない場合
引数で複数の値を渡すが文字列リソースで使わない場合の挙動
<string name="string_res2">2番目のみ%2$s"</string>
getString(R.string.string_res2, "A", "B") 結果: 2番目のみB
特に問題なく文字列が取得できる
必要以上に値を渡した場合
1番目の引数のみ使う文字列リソースに2つの値を渡した場合
<string name="string_res3">1番目%1$s"</string>
getString(R.string.string_res3, "A", "B") 結果: 1番目A
実行時には問題なく文字列が取得できる
ただしlintでの警告がでる
values-ja/strings.xml
を作成して日本語の場合に2つの値を使うようにしても警告がでた
DataBindingでincludeしたレイアウトに値を渡す メモ
AndroidのDataBindingでincludeしたレイアウトに値を渡す時に少し悩んだのでメモ
変数の渡し方法
includeされるファイルが以下のような時
<?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:bind="http://schemas.android.com/apk/res-auto"> <data> <variable name="user1" type="com.example.User"/> </data> <merge> <include layout="@layout/name" bind:user="@{user1}"/> <include layout="@layout/contact" bind:user="@{user1}"/> </merge> </layout>
includeする側のレイアウトではbind:hoge
属性を使って変数を渡すことができる
hoge
の部分にはlayout
で指定したファイル内の変数名を指定する(今回の場合はuser1)
<data> <variable name="user2" type="com.example.User"/> </data> <LinearLayout ...> <include layout="@layout/name" bind:user1="@{user2}"/ </LinearLayout>
参考にした公式サイトの情報ではbind:user="@{user}"
となっていてすこしわかりづらいですね・・・
リソースファイルの値を渡す方法
もし、includeするlayoutにリソースファイルの値を渡したい時の例
例: Stringの値を受け取ることができるレイアウトファイル
"@{@string/app_name}"
のように指定すると良い
<data> <variable name="title" type="String"/> </data>
<include layout="@layout/layout_text" bind:title="@{@string/app_name}" />
Backgroundに設定した画像を拡大させない方法
AndroidのViewのbackgroundに画像を設定した場合にViewのサイズに合わせて画像も拡大されます
通常は特に問題ないのですがどうしても画像を拡大させたくない場合がある時の対処方法を紹介します
今回は24x24dpの以下のような画像を使いました (AndroidStudioのImageAssetで作りました)
画像サイズを維持するDrawableを作成する
以下のようなDrawableファイルを使うことで画像サイズを維持するDrawableを作成することが可能になります
<?xml version="1.0" encoding="utf-8"?> <bitmap xmlns:android="http://schemas.android.com/apk/res/android" android:gravity="center" android:src="@drawable/ic_weekend"/>
最低限必要なのはsrc
のみで表示したい画像を設定します
gravity
を設定することで表示位置を変更できます
実際の表示
以下のようなレイアウトを設定して表示を確認してみます
48x48dpと12x12dpの2通り
<View android:layout_width="48dp" android:layout_height="48dp" android:background="@drawable/ic_weekend" /> <View android:layout_width="48dp" android:layout_height="48dp" android:background="@drawable/no_scale_ic_weekend" /> <View android:layout_width="12dp" android:layout_height="12dp" android:background="@drawable/ic_weekend" /> <View android:layout_width="12dp" android:layout_height="12dp" android:background="@drawable/no_scale_ic_weekend" />
2,4番目が今回作った、サイズを維持するdrawableを表示した場合です
1番目は拡大されて表示していますが2番目では期待通り24x24dpの表示になっています
おまけですが12x12dpの場合も見てみました
ただの画像を表示した場合はサイズに合わせて縮小されていますが、今回つくってDrawableでは一部分のみしか表示されていませんでした
まとめ
固定画像のサイズをViewのBackgroundに設定する際にはbitmap要素のDrawableファイルを作成すると良いようです
画像サイズより大きいViewのbackgroundに画像を表示する場合は問題ないですが、
小さいViewに設定する際には一部分のみしか表示されないので注意する必要があります
ProgressBar用にDrawableを作成メモ
基本的にはdraw
の中で描画をしてあげるだけで良い
動きをつける場合にはgetLevel()
で取得できる値を元に行うと簡単
getLevel()
の値の範囲は[0, 10000]
サイズの変更はonBoundsChange(Rect)
で受け取れる(draw
の前に最初に呼ばれるが必ずそうなのかは要調査)
public class MyDrawable extends Drawable { private static final int INDICATOR_COUNT = 12; private static final int MAX_LEVEL = 10000; private RectF rectF = new RectF(); private Paint p; private int centerX; private int centerY; private int width; private int height; public MyDrawable() { p = new Paint(); } @Override public void draw(@NonNull Canvas canvas) { int duration = MAX_LEVEL / 4; int currentPos = ((getLevel() % duration) / (duration / INDICATOR_COUNT)) % INDICATOR_COUNT; for (int i = 0; i < INDICATOR_COUNT; i++) { // 先頭との差によって色を変える[0xaaaaa, 0xffffff]の範囲で int diff = ((currentPos + INDICATOR_COUNT) - i) % INDICATOR_COUNT; diff = Math.max(Math.min(diff, 0x4), 0x0); p.setColor((0xff000000 | (0x00111111 * (0xf - diff)))); float r = 32 * width / 100f; canvas.drawRoundRect(rectF, r, r, p); canvas.rotate(360f / INDICATOR_COUNT, centerX, centerY); } } @Override public void setAlpha(int i) { } @Override public void setColorFilter(ColorFilter colorFilter) { } @Override protected void onBoundsChange(Rect bounds) { super.onBoundsChange(bounds); centerX = bounds.centerX(); centerY = bounds.centerY(); width = bounds.width(); height = bounds.height(); float scale = width / 100f; rectF.set(centerX + 24 * scale, centerY - 4 * scale, width - 2 * scale, centerY + 4 * scale); } @Override public int getOpacity() { return PixelFormat.TRANSLUCENT; } }
今回作ったものは以下のような表示をする(背景は別で灰色にしています)
setAlpha
やsetColorFilter
については調べられてないので調べる必要がある
また、getLevel
を使う以外にもアニメーションを行える方法があるようなので他の方法も調べたい
AndroidのRotateDrawableで回転速度を調整する
RotateDrawableとは
RotateDrawableはDrawableを回転させることができるDrawableで、以下のようなdrawableファイルを作成することで使うことが可能になります
<?xml version="1.0" encoding="utf-8"?> <rotate xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/ic_action_reload" android:pivotX="50%" android:pivotY="50%" />
今回はRotateDrawableの回転速度を変更することができないか調査してみました
drawableファイル内で速度を変更させる
drawableファイル内で速度を変更するにはfromDegrees
とtoDegrees
の値を設定することで変更できます
toDegrees=0, fromDegrees=360
とtoDegrees=0, fromDegrees=3600
を比較すると後者が10倍ほど早く回転します
<?xml version="1.0" encoding="utf-8"?> <rotate xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/ic_action_reload" android:fromDegrees="0" android:pivotX="50%" android:pivotY="50%" android:toDegrees="3600" />
API21時点ではデフォルト値は以下のようになっているようです
float mFromDegrees = 0.0f; float mToDegrees = 360.0f;
実際の動作
今回はProgressBarを使って表示を行いました
<ProgressBar android:layout_width="64dp" android:layout_height="64dp" android:indeterminateDrawable="@drawable/rotate_default" />
結果は以下のようになりました
(toDegrees,fromDegrees)
の値は,
左から, (指定なし,指定なし), (0,360), (0, 3600)です