1. はじめに
こんにちは!エンジニアとして、初めてカーナビ関連の案件に参画しました。
参画当初は「プローブデータ」「LBS」「オンロード/オフロード」といった専門用語の理解に苦しみ、さらには複数のSDKが入り混じっていたため、「今書いているコードはアプリ側なのか?SDK側なのか?」と、境界線がわからず混乱することもありました。
今回は、ProbeData SDKという機能の修正や試験、ドキュメント準備に携わる中で、改めて復習し、ようやく腑に落ちた 「リスナー(Listener)」 の基本構造についてまとめてみたいと思います。
2. リスナーの役割:なぜ必要なのか?
リスナーを言語化しようとすると意外と難しいですが、私は以下のように整理しました。
- SDK側:データを収集する機能は持っているが、「データが取れた後に、それぞれのアプリが何(表示、ログ、保存など)をしたいか」 は知らない。
- アプリ側:データが欲しいタイミングは知っているが、「どうやって低レイヤーのデータを集めるか」 の詳細は知らない。
この両者を繋ぐのが「リスナー」です。アプリ側で処理内容を記述した「予約票」をSDKに渡しておき、SDK側でイベントが発生した瞬間にその予約票を実行してもらう、というイメージです。
3. SDKで定義したリスナーをアプリで呼び出す流れ
実務でよく見かける、SDK側でインターフェースを定義し、アプリ側でその中身(実装)を記述する例を見てみましょう。
① SDK側:インターフェースの定義
SDK側で「データが取れた時」と「送信が終わった時」のルールを決めます。
// SDK側の定義
interface ProbeDataListener {
// データ(位置情報や車両情報)が収集された時に呼ばれる
fun onDataCaptured(data: String)
// サーバーへのアップロード結果を通知する
fun onUploadResult(isSuccess: Boolean)
}
② SDK側:リスナーを保持し、実行する
SDK側はアプリからリスナーを受け取る窓口を作り、内部でデータが溜まったらそれを実行します。
class ProbeDataSDK {
private var listener: ProbeDataListener? = null
// アプリ側からリスナーを登録(Add/Set)してもらうメソッド
fun setListener(listener: ProbeDataListener) {
this.listener = listener
}
// SDK内部で定期的に実行されるデータ処理(イメージ)
private fun handleDataCollection() {
val currentInfo = "Lat: 35.6, Lng: 139.7, Speed: 60km/h"
// ★ここで「アプリ側で書かれた処理」が実行される!
listener?.onDataCaptured(currentInfo)
}
}
③ アプリ側:リスナーを登録して処理を動かす
アプリ起動時の初期化処理などで、SDKにリスナーを渡します。
// アプリ側の実装
val probeDataSdk = ProbeDataSDK()
// 初期化の流れでリスナーを登録
probeDataSdk.setListener(object : ProbeDataListener {
override fun onDataCaptured(data: String) {
// SDKからデータが届いた!ログに出して確認しよう
Log.d("ProbeData", "収集データを受信: $data")
}
override fun onUploadResult(isSuccess: Boolean) {
if (isSuccess) {
Log.d("ProbeData", "アップロード成功!")
} else {
Log.e("ProbeData", "アップロード失敗...")
}
}
})
4. 現場での動作確認:Logcatの活用
実装した機能が正しく動いているかは、主にAndroid StudioのLogcatで確認しました。
-
アプリを起動して初期化が走った後、車が走っていなくても設定された頻度でデータが収集されているか?
-
収集された座標や車両情報の「鮮度」は新しいか?
-
一定時間経ってアップロードが走った際、onUploadResult が成功を返しているか?
実際のログを追いながら、SDK内部の動きとアプリ側の受け取りが一致した瞬間は、とてもスッキリしました!
5. 終わりに
最初は「SDK側とアプリ側、どっちを触っているんだっけ?」と迷うこともありましたが、リスナーの構造(定義・登録・実行)を整理することで、データの流れがクリアに見えるようになりました。
カーナビ案件のような大規模なプロジェクトでは、こうした基本的なデザインパターンが至る所で使われています。一つずつ仕組みを解明していくことが、成長への近道だと感じました。
この記事が、SDK開発やリスナーの理解に悩む方の参考になれば幸いです!