Android AppWidgetProviderのインスタンス調査


widget間で値共有できるか調査してみたのでメモ

Widgetごと、ライフサイクルごとにインスタンスが生成されているみたい。なので、いくらこういうことをしても

class MyWidget : AppWidgetProvider() {

    private var numberCount = 0

    override fun onUpdate(context: Context,
        appWidgetManager: AppWidgetManager, appWidgetIds: IntArray)
    {
        Log.d("lifecycle", "Update")
        Log.d("lifecycle", this.toString())
        numberCount += 1
        for (appWidgetId in appWidgetIds) {
            updateAppWidget(
                context, appWidgetManager, 
                appWidgetId, numberCount.toString()
            )
        }

    override fun onEnabled(context: Context) {
        Log.d("lifecycle", "Enable")
        numberCount += 1
        Log.d("lifecycle", this.toString())
    }

    override fun onDisabled(context: Context) {
        Log.d("lifecycle", "Disable")
        Log.d("lifecycle", this.toString())
    }

    companion object {

        internal fun updateAppWidget(
            context: Context, appWidgetManager: AppWidgetManager,
            appWidgetId: Int, numberCount: String
        ) {

            // Construct the RemoteViews object
            val views = RemoteViews(context.packageName, R.layout.my_widget)
            views.setTextViewText(R.id.appwidget_text, numberCount)

            // Instruct the widget manager to update the widget
            appWidgetManager.updateAppWidget(appWidgetId, views)
        }
    }
}

すべてのWidgetで"1"となる。onEnableが着火したWidgetも"1"なので注意。

logはこんな感じ。インスタンスIDが各lifecycleごとに違うのがわかる

2019-05-30 19:12:06.960 12210-12210/jp.letitride.mystudywidget D/lifecycle: Enable
2019-05-30 19:12:06.960 12210-12210/jp.letitride.mystudywidget D/lifecycle: jp.letitride.mystudywidget.MyWidget@a438aaa
2019-05-30 19:12:06.963 12210-12210/jp.letitride.mystudywidget D/lifecycle: update
2019-05-30 19:12:06.963 12210-12210/jp.letitride.mystudywidget D/lifecycle: jp.letitride.mystudywidget.MyWidget@c7e069b
2019-05-30 19:12:45.655 12210-12210/jp.letitride.mystudywidget D/lifecycle: Disable
2019-05-30 19:12:45.655 12210-12210/jp.letitride.mystudywidget D/lifecycle: jp.letitride.mystudywidget.MyWidget@79c0a11

よって、onEnabledで別ライフサイクルや他Widgetに状態を共有するには、companion object {}内でメンバを扱ったり

override fun onEnabled(context: Context) {
    numberCount += 1
}

companion object {
    var numberCount = 0
    // ... 中略
}

または、onReceive()intent.actionでイベントハンドルしつつintentのExtraで情報の受け渡しするのが良さそう。

この画像は同Widgetを複数配置した時のcompanion object内に記述したstaticフィールドでの値参照。

f:id:letitride:20190530194959p:plain