現象
AppWidget配置時の設定画面を中断すると、見えないAppWidgetが生成されてシステム上に残り続ける。
見えないAppWidgetインスタンスが存在し続けるため、次に新たなAppWidgetを配置して削除した場合でも、AppWidgetProviderでのonDisabledが呼ばれないことになる。
詳細
AppWidgetは、新規配置時に表示する設定アクティビティをAppWidgetProviderInfoのandroid:configureで指定できる。
設定アクティビティがRESULT_OKかつ、ExtraにappWidgetId格納されている状態で終了すると、新規ウィジェットが配置される。
RESULT_CANCELで終了すると、ウィジェットの配置は行われない。
しかし、AppWidgetProviderでのonUpdate時に渡されるIDsには、ウィジェットが残ってしまっている。
また、キャンセル時にonDeletedが呼ばれる事もない。
さらに、ホーム画面から見えている全ウィジェットを削除してもonDisabledが呼ばれない。
つまり、不可視で削除不可のAppWidgetインスタンスが存在しているような状態になる。
なお、キャンセル以外のBackボタン・Homeボタン・電源ボタン押下によるアクティビティの中断でも同様の状況となる。
影響
この件で出来てしまったゾンビAppWidgetがどの程度リソースを圧迫するかは不明。
onDisabledが実行されないのが痛手で、ここに後処理を入れていると、画面上からウィジェットが消えても呼ばれない事になる。
対処方法
設定アクティビティをRESULT_CANCELで終了させず、必ずRESULT_OKで終了する。設定を中断した場合、内容が空のウィジェットを表示させ、ユーザーに手動で削除してもらう。
他に検討した案
設定完了していないウィジェットはonUpdateで破棄
設定アクティビティ起動前にまずウィジェットのonUpdateが呼ばれるため、設定前なのか設定中断後なのかの判別が難しい。設定中にonUpdateが走った場合なども考える必要がある。
設定アクティビティのonPauseなどで設定中断を検知して破棄
電源断などでハンドラが呼ばれない場合がある。
関連URL
AndroidのIssues(2009年には報告済だがなぜか未対応)
日本アンドロイドの会の関連投稿
StackOverFlow
ドキュメントのAppWidgetガイド