たくさんの自由帳
Androidのお話
たくさんの自由帳
投稿日 : | 0 日前
文字数(だいたい) : 1080
ねむい
ライフサイクルのコールバックをActivity/Fragment以外のクラスで受け取りたいって話。
こんなふうなセンサーの値をとるクラスがあったとして、
/**
* 加速度センサーの値取得クラス
* @param activity Contextとるため
* @param sensorChanged センサーの値が変更された時に呼ばれる高階関数
* */
class GetSensor(activity: Activity, sensorChanged: (SensorEvent?) -> Unit) {
private val sensorManager = activity.getSystemService(Context.SENSOR_SERVICE) as SensorManager
private var sensorEventListener: SensorEventListener
init {
sensorEventListener = object : SensorEventListener {
override fun onAccuracyChanged(p0: Sensor?, p1: Int) {
}
override fun onSensorChanged(p0: SensorEvent?) {
// 値が変更された
sensorChanged(p0)
}
}
}
/** 終了時に呼んでね */
fun destroy() {
sensorManager.unregisterListener(sensorEventListener)
}
/** 開始時に呼んでね */
fun start(){
// 加速度センサー
val sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
// センサー登録
sensorManager.registerListener(
sensorEventListener,
sensor,
SensorManager.SENSOR_DELAY_NORMAL
)
}
}
MainActivity.kt
あたりで使うとして、こうですね
class MainActivity : AppCompatActivity() {
private lateinit var sensor: GetSensor
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
sensor = GetSensor(this) {
// X軸を出力
println(it?.values?.get(0))
}
}
// センサーの登録解除
override fun onPause() {
super.onPause()
sensor.destroy()
}
// センサーの登録
override fun onResume() {
super.onResume()
sensor.start()
}
}
(activityじゃなくてcontextで良いだろ)
onPause()
に書き忘れる可能性があるGetSensor
クラスで登録とか解除とかを自動でやってほしい
onPause
とかに書かないといけないの?これを使うと、
DESTROY
状態になったら呼ばれる関数(べつにSTARTでも良いよ)
ライフサイクルはクソなので助かる
なので書き直すと
LifecycleObserver
は実は中身空っぽなので書き足すだけでいいです
class GetSensor(activity: Activity, sensorChanged: (SensorEvent?) -> Unit) : LifecycleObserver {
GetSensor
クラスのコンストラクタの引数にlifecycle: Lifecycle
を付け足します。
class GetSensor(activity: Activity, lifecycle: Lifecycle, sensorChanged: (SensorEvent?) -> Unit) : LifecycleObserver {
そしてinit{ }
の中に以下の1行を足します
lifecycle.addObserver(this)
@OnLifecycleEvent
をつけるまず忘れそうなdestroy()
関数につけましょう。
ちゃんとコメントも書き換えて、privateにしてしまいましょう(勝手に呼ばれるのでもう書く必要がないため)。
/** 終了時に勝手に呼ばれる */
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
private fun destroy() {
sensorManager.unregisterListener(sensorEventListener)
}
それとセンサーを登録する関数も、ライフサイクルがResume
の状態になったら自動で呼ぶようにします
/** 開始状態になったら勝手に呼ばれる */
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
private fun start() {
// 加速度センサー
val sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
// センサー登録
sensorManager.registerListener(
sensorEventListener,
sensor,
SensorManager.SENSOR_DELAY_NORMAL
)
}
最後にMainActivity
を修正して終わりです!
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
GetSensor(this, lifecycle) {
// X軸を出力
println(it?.values?.get(0))
}
}
}
わあ!すごいスッキリ
実行してLogcatを出してアプリを離れると勝手に出力が終了し、また戻ってくると出力が始まってることが分かるはずです。
GetSensor.kt
/**
* 加速度センサーの値取得クラス
* @param activity Contextとるため
* @param sensorChanged センサーの値が変更された時に呼ばれる高階関数
* */
class GetSensor(activity: Activity, lifecycle: Lifecycle, sensorChanged: (SensorEvent?) -> Unit) :
LifecycleObserver {
private val sensorManager = activity.getSystemService(Context.SENSOR_SERVICE) as SensorManager
private var sensorEventListener: SensorEventListener
init {
lifecycle.addObserver(this)
sensorEventListener = object : SensorEventListener {
override fun onAccuracyChanged(p0: Sensor?, p1: Int) {
}
override fun onSensorChanged(p0: SensorEvent?) {
// 値が変更された
sensorChanged(p0)
}
}
}
/** 終了時に勝手に呼ばれる */
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
private fun destroy() {
sensorManager.unregisterListener(sensorEventListener)
}
/** 開始状態になったら勝手に呼ばれる */
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
private fun start() {
// 加速度センサー
val sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
// センサー登録
sensorManager.registerListener(
sensorEventListener,
sensor,
SensorManager.SENSOR_DELAY_NORMAL
)
}
}
MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
GetSensor(this, lifecycle) {
// X軸を出力
println(it?.values?.get(0))
}
}
}
https://developer.android.com/topic/libraries/architecture/lifecycle?hl=ja