Android Java GC周りのまとめ。
- Android JavaのGCはCMS(Concurrent Mark&Sweep)
- JVMはAndroid5.0以前は Dalvik VM、5.0以降はARCがデフォルトで、GCアルゴリズムは共にCMSベース。
- AndroidのGCはオブジェクトをルートから辿って、辿りつかない場合は解放する。そのため循環参照になっていても上位のオブジェクトからの参照が切れていれば問題ない。
- オブジェクトがライフサイクル内で閉じて入れば問題ないが、ライフサイクルを超えて利用される場合はいつまでも解放されない可能性が出て来るので注意する。その場合は弱参照を利用したり設計を見直す。
- GCを助けるために不要になったオブジェクトはなるべくnullクリアしておく。
参考サイト
メモリーモニター -Android Studio ドキュメント 日本語訳
第2回 ヒープが再利用される仕組みを理解する:Javaはどのように動くのか~図解でわかるJVMの仕組み|gihyo.jp … 技術評論社
不要になった変数に NULL を代入する (Sun Java System Application Server Enterprise Edition 8.2 パフォーマンスチューニングガイド)
Memory Profiler を使用して Java ヒープとメモリ割り当てを表示する | Android Studio
Java/AndroidとJVM + Heap + Gabage Collectionのお話 - Qiita
Android実機からdbやfileをpullするバッチ(windows用)
実機のdbをユーザーホームにコピー
rem cd %HOMEDRIVE%%HOMEPATH%\AppData\Local\Android\sdk\platform-tools\ adb shell run-as your.package.name cp databases/db_name.db /mnt/sdcard/ adb pull /mnt/sdcard/db_name.db %HOMEDRIVE%%HOMEPATH%/db_name.db exit
fileをコピー
rem cd %HOMEDRIVE%%HOMEPATH%\AppData\Local\Android\sdk\platform-tools\ adb shell run-as your.package.name cp -R files /mnt/sdcard/app_data_files adb pull /mnt/sdcard/app_data_files %HOMEDRIVE%%HOMEPATH%\app_data_files exit
Android開発小ネタと参考リンク
小ネタと参考リンク
テキスト入力
- サロゲートペア対策(絵文字とか) 文字数カウントはString#lengthではなくString#codePointCountを使う
カメラ、ギャラリー
- 画像の向きをチェックし角度を修正しないと正しい向きで写真が表示されない
- 内部ストレージに画像を保存出来ない機種がある(305SH)ExternalStrageがnullになるかチェック等入れる必要あり
画像
- 画像は小さいサイズで読み出す
- ListViewではLRUCacheとか使う
- getDrawingCache() で null が返ってくることがあったり
メモリ
- 例えばAsyncTaskにViewを渡すならActivityが死ぬ事も考慮してAsyncTaskがViewの参照を保持し続けないようにWeakRefを使った方が良いが、普通にAsyncTaskLoaderを使った方が良い
ダイアログ
- DialogFragmentを利用する。リスナーはクライアントのActivityかFragmentに実装し、DialogFragmentのonAttachでリスナーをimpleしているかチェックする。setHoge等でセットするべきではない(再生成時にセットされなくなる)
- width,heightのリサイズはDialogFragment#onStartでlayoutParameterをgetDialogしてセットしてやると変わる。onAttachでやるとか言ってるけどそれだと変わらない?
端末の文字フォント
- 文字サイズは基本端末のフォント設定に追従する。させたくない場合はspでなくdpを使う。Lint警告を抑制したい場合は'SpUsage'を無視する。
listView
- スクロールバーを外側に表示するのはclipToPadding=false , scrollBarStyle=“outsideOverlay” そしてparentにpaddingを付けない。
- ListViewの子要素のonClickListenerはそのままだと拾えないので、ルートViewの属性に android:descendantFocusability=“blocksDescendants"を追加する。
DB
- SQLiteのDBはいちいちCloseするなとか言っているけど都度Closeする。そうしないとLeakする。
音声入力
- マイクを使う場合、他のアプリ等で競合が発生していないか検討し、競合の場合の処理を考慮する。Androidの場合は先勝ちになるのでAudioRecord初期化失敗で競合を検出する等をやる。
スレッド
- handlerはプロセス間通信が可能
- AsyncTaskは数秒程度の短い処理なら使っても良いがActivityが死んでるかもしれないので基本AsyncTaskLoaderを使う。
- Activityの死活が関係なくViewも操作しない場合はThreadでやってOk。
アプリ内課金
- google play がキャッシュしてくれるので、アプリ側ではキャッシュを作らないようにする。
- 実機でテストしないとダメ。エミュレーターじゃダメ。
AndroidStudioでIInAppBillingService.aidlは以下に配置する。 /src/main/aidl/com/android/vending/billing/IInAppBillingService.aidl
テストはコンソールに登録したアカウントでないといけない。APKをアップロードしていないといけない。公開状態にしないといけない。
あんざいさんによるIn-app Billingうまくいかないパターン。
In-app Billingうまくいかないパターン。1. 開発者と同じアカウントで購入しようとした 2. リリース前に購入しようとした場合、購入しようとしたアカウントを販売者アカウントのページでテストアカウントに設定していない 3. 購入リクエストを送りすぎではじかれる (続く)
— Yuki Anzai (@yanzm) 2011年8月22日In-app Billing うまくいかないパターン続き 4. マーケットにある apk のバージョンと端末に入れているバージョンが違う(android:versionCode が違う(versionCode が同じならバイナリが一致しなくても大丈夫))(続く)
— Yuki Anzai (@yanzm) 2011年8月22日In-app Billing うまくいかないパターン続き(その2)5. 端末にいれている apk がリリース署名されていない。 こんなとこかな。
— Yuki Anzai (@yanzm) 2011年8月22日
NDK
- 複数のNDKライブラリを使っている場合に特定の環境でクラッシュするケース。
- ライブラリAが armeabi arm-v7a arm-v8a のディレクトリにそれぞれのバイナリがあり、かつ ライブラリBが arm-v8aに対応しないバイナリの場合、 64ビットマシンで実行するとarm-v8aにバイナリを観に行くようになるので、 ライブラリBが見つからなくてクラッシュする。
その他の参考にさせていただいたページ
画像
ギャラリーからの画像読み込みでエラーが出るときの修正方法 | Workpiles
カメラ
ストレージ
android.iku4.com
blog.lciel.jp
ダイアログ
パーミッション
canvas
DB
developer.android.com サルでもわかる 逆引きデザインパターン 第3章 逆引きカタログ J2EE編 DAO(Data Access Object)