DiffUtilのgetChangePayloadで返したオブジェクトをどう使うか

DiffUtilのgetChangePayloadでは、古いアイテムと新しいアイテムでどのフィールドが更新されたかの情報を詰めたオブジェクトを生成して返す。

どんな感じなのかは以下のサイトを参照。

このreturnするPayloadがどこで使われるかちゃんとわかって無かったのだけど、onBindViewHolder(ViewHolder holder, int position, List<Object> payloads)payloadsで参照できる。

RecyclerView.Adapter  |  Android Developers

areItemsTheSame(int, int)trueを返し、areContentsTheSame(int, int)falseを返すなら、新旧のitemエンティティ(一意に識別できるオブジェクト)自体は同じだが、そのオブジェクトの持つデータが異なる。

どのデータが新しいデータで更新されたかをgetChangePayloadでオブジェクトにして返してやり、onBindViewHolder(ViewHolder holder, int position, List<Object> payloads)でpayloadsから更新内容を取得してViewを部分的に更新してやればゼロからViewを構築するよりコストが下がる。

この時アニメーションを掛けて更新すると良い感じになる。なるほど。

LiveDataのユニットテストを書く際に参考になる記事

LiveDataのユニットテストを書く場合にどうするか調べたのでメモ。

LiveDataのUnitTest – Kenji Abe – Medium

How To Unit Test LiveData and Lifecycle Components – ProAndroidDev

  • KotlinでLiveDataとlifecycleのユニットテストについて解説している記事。lambdaMockという関数を用意しているのがポイント。
  • Lifecycleのユニットテストについても言及している。
  • ProAndroidDevは参考になる記事が多いですね。

LiveDataの基礎的な性質を整理する。 - Qiita

  • LiveDataの性質についてまとめられた記事です。LiveDataがどのような挙動をするかがテストコードを交えてわかりやすく解説されています。
  • LiveDataの性質についてだけで無く、テストコードの書き方についても参考になりました。

Mockito

Mockitoの使い方については、こちらのブログがとても参考になります。ありがたい🙏

Mockito カテゴリーの記事一覧 - R42日記

It’s time to upgrade GCM to Firebase Cloud Messagingの意訳

FirebaseからGCM終了のお知らせとFCMへのアップグレード告知メールが来たので意訳した。ついにGCMが終了するのかー

意訳文

2016年、Google Cloud Messaging(GCM)の後継としてFirebase Cloud Messaging(FCM)をローンチしました。FCMはGCMを進化させ、通知とデータメッセージをiOSAndroidの両方に確実に送信することを可能にしています。加えて、FCMはFirebase console上でプッシュ通知を簡単に送信できる機能を提供しています。それによって、ユーザーの再獲得のためのプッシュ通知を簡単に送信できます。

FCMの改善のために注意を払い多くの時間を掛けた事で、今日私達は開発者の皆さんに来年FCMへアップグレードする必要がある事を告知する事ができました。GCMサーバとクライントAPIは非推奨になり、2019年4月11日にすみやかに削除されます。私達は、出来る限り速くFCMにアップグレードし、FCMが提供する便利な機能のアドバンテージを得る事を推奨します。

もしあなたのプロジェクトでまだGCM APIを使用しているなら、2019年4月11日までにクライアントとサーバーのコードでFCMを使用するよう更新する必要があります。今使用しているGCMトークンはFCMで引き続き動作するため既存のユーザーへプッシュ通知が送信不能にはなりません。

何をする必要があるのか?

こちらからFCMへのアップグレードプロセスを確認できます。また、こちらの動画でもマイグレーションプロセスを確認できます。

もしドキュメントで回答が得られない質問があれば、サポートページのCloud Messaging FAQsをご覧頂くかその他のサポートチャンネルを通じてご連絡ください。

あなたをFCMへ迎える事を楽しみにしています!

Firebaseチームより。

原文

In 2016, we launched Firebase Cloud Messaging (FCM), the successor to Google Cloud Messaging (GCM). As the next evolution of GCM, Firebase Cloud Messaging allows you to send notifications and data messages reliably to iOS, Android, and the Web at no cost. In addition, FCM provides you with new features like the easy-to-use notifications interface in the Firebase console, so you can easily target and test notifications to re-engage your users.

In order to devote more time and attention to improving FCM, today we’re announcing that you must upgrade to FCM in the next year. The GCM server and client APIs are deprecated and will be removed as soon as April 11, 2019. We recommend you upgrade sooner rather than later so you can start taking advantage of the new features in FCM today.

If you have projects that are still using the GCM APIs, you will need to update your client and server code to use FCM before April 11, 2019. Your existing GCM tokens will continue to work with FCM so you won’t lose the ability to send to your existing users.

What do I need to do?

You’ll find a complete walkthrough of the FCM upgrade process here. You can also check out this video, which walks through the migration process.

If you have questions that aren’t answered in the deprecation documentation, take a look at the Cloud Messaging FAQs on our support page or reach out to us through one of our other support channels.

We look forward to welcoming you to FCM!

Thanks,

Firebase Team

Advertising IDの取得

毎回忘れるので取得の仕方をメモしておく。

仕様・実装方法

仕様や実装については以下を見ておけば恐らくOK。

Advertising ID | Android Developers

AdvertisingIdClientのリファレンスは以下を参照。

https://developers.google.com/android/reference/com/google/android/gms/ads/identifier/AdvertisingIdClient

実装

Advertising IDを取得するには、プロジェクトにplay-services-adsを追加する必要がある。appモジュールレベルのbuild.gradleのdependenciesに以下を追加。

implementation "com.google.android.gms:play-services-ads:$play_services_version"

getAdvertisingIdInfoはUI Threadで取得するとIllegalStateExceptionを吐くため、別Threadで実行する必要がある。AsyncTaskがツライのでKotlinのcoroutineを使うとスッキリと書ける。

// 別Threadで実行
launch {
    // Advertising IDを取得
    val id = try {
        AdvertisingIdClient.getAdvertisingIdInfo(context).id
    } catch (e: Exception) {
        null
    }
}

potatotipsで発表してきました

先週potatotips #48で「Alexa、APKを配布して」というタイトルで発表してきました。Rettyさんありがとうございました。

資料はこちらです。

続きを読む

Support Libraryを27.1.0に更新した際に行った事のメモ

Support Library 27.1.0が公開されていたので更新しました。その際に行った作業のメモ。

developer.android.com

RecyclerView.Adapterの抽象メソッドが取る引数の型を変更

onCreateViewHolder、onBindViewHolderでそれぞれViewGroup、RecyclerView.ViewHolderがnon-null型に変更されていたので対応。

com.android.build.api.transform.TransformExceptionの対応

--stacktraceを付けてビルドすると以下のようなExceptionが発生してたので対応。ListAdapterが重複しているのが原因らしい。

Dex: Error converting bytecode to dex:
Cause: com.android.dex.DexException: Multiple dex files define Landroid/support/v7/recyclerview/extensions/ListAdapter;
    UNEXPECTED TOP-LEVEL EXCEPTION:
    com.android.dex.DexException: Multiple dex files define Landroid/support/v7/recyclerview/extensions/ListAdapter;

com.android.dex.DexException: Multiple dex files define Landroid/support/v7/recyclerview/extensions/ListAdapter;
        at com.android.dx.merge.DexMerger.readSortableTypes(DexMerger.java:661)
        at com.android.dx.merge.DexMerger.getSortedTypes(DexMerger.java:616)
        at com.android.dx.merge.DexMerger.mergeClassDefs(DexMerger.java:598)
        at com.android.dx.merge.DexMerger.mergeDexes(DexMerger.java:171)
        at com.android.dx.merge.DexMerger.merge(DexMerger.java:198)
        at com.android.builder.dexing.DexArchiveMergerCallable.call(DexArchiveMergerCallable.java:61)
        at com.android.builder.dexing.DexArchiveMergerCallable.call(DexArchiveMergerCallable.java:36)
        at java.util.concurrent.ForkJoinTask$AdaptedCallable.exec(ForkJoinTask.java:1424)
        at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
        at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
        at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
        at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)

Paging Library 1.0.0-alpha6でSupport Library 27.1.0にListAdapterが移ったとのこと。そのためPaging Library 1.0.0-alpha6未満とSupport Library 27.1.0を同時に使用するとListAdapterが重複する。

https://developer.android.com/topic/libraries/architecture/release-notes.html#february_27_2018

解決策として、Paging Libraryを1.0.0-alpha6に更新したところExceptionは発生しなくなった。

Multidex Support Libraryのバージョンを更新

27.1.0対応とは関係無いが、1.0.3がリリースされているのに気づいたのでまとめて更新した。