◉ANTIGRAVITY LABEN
記事一覧/アプリ開発
▣ アプリ開発/2026-07-09上級

バックグラウンド更新は来ないことがある — 実行機会を測り、鮮度から設計をやり直した記録

BGTaskScheduler と WorkManager の実行機会は申請すれば得られるものではありません。実行率をログで測り、鮮度をSLOとして定義し、来ない前提の三層フォールバックへ組み直した設計を、計測コードとともに残します。

BGTaskSchedulerWorkManagerバックグラウンド処理Antigravity377アプリ設計

✦ プレミアム記事

壁紙アプリの利用者から「もう三日も同じ絵のままです」という連絡をいただいたのは、深夜のことでした。

私の手元の端末では、毎朝きちんと絵が切り替わっています。再現しません。ログを引き出して、ようやく事情が飲み込めました。バックグラウンド更新のタスクは、確かに登録されていました。ただ、一度も実行されていなかったのです。

登録は申請にすぎません。実行されるかどうかは、OS が決めます。頭では理解していたはずのその一行が、実際の端末の上ではまったく違う重みを持っていました。

「毎朝更新される」という前提が崩れていた

私が組んでいたのは、素朴な設計でした。深夜に BGAppRefreshTask を予約し、翌朝の起動前に次の壁紙を用意しておく。Android 側は PeriodicWorkRequest で 24 時間ごとに同じことをする。ウィジェットは、そうして用意された画像を読むだけ。

シミュレータでは完璧に動きます。私の iPhone でも動きます。私は毎日そのアプリを開き、充電しながら寝る人間だからです。

利用者は違いました。低電力モードを常用する方。アプリを週に一度しか開かない方。バッテリー最適化の対象にアプリを入れている方。そうした端末では、タスクは予約されたまま順番が回ってこず、ウィジェットは何日も前の画像を表示し続けます。

不具合ではありません。仕様どおりの挙動です。設計が現実を見誤っていただけでした。

実行機会は、申請ではなく抽選である

iOS と Android で言葉づかいは違いますが、構造はよく似ています。アプリは「やりたいこと」を宣言し、OS は端末の状態を見て、実行してよい瞬間を割り当てます。割り当てられない日もあります。

観点 iOS(BGTaskScheduler) Android(WorkManager)
最短間隔 earliestBeginDate は下限の希望。上限の保証はない PeriodicWorkRequest の最短は 15 分。実行は Doze の窓に依存
実行時間 App Refresh は概ね 30 秒程度で expirationHandler が呼ばれる Worker は 10 分。超えると isStopped が立つ
抑制する主因 低電力モード、アプリの起動頻度、充電・通信状態 Doze、App Standby Bucket、メーカー独自の最適化
再起動後 予約は保持される(アプリ更新時は再登録が必要) 永続化されるが、強制停止後は再登録まで動かない
失敗の可視性 実行されない事実はどこにも記録されない WorkInfo に状態は残るが、間引きの理由は残らない

最後の行が、この問題のいちばん厄介なところです。実行された記録は残ります。実行されなかった記録は、どこにも残りません。だから気づけません。

Android の App Standby Bucket は、その端末でのアプリの使われ方に応じて active / working_set / frequent / rare / restricted と段階が下がっていきます。週に一度しか開かれないアプリが rare に落ちれば、定期実行の窓は一日に一度あるかどうかまで狭まります。私のアプリはまさにそこにいました。

✦

ここまでお読みいただきありがとうございます。

この記事の続きを読む

この先には、実装コードやベンチマーク結果など、実務でお役に立てる内容をご用意しています。このサイトは広告を掲載しておらず、サーバーや開発にかかる費用はメンバーの皆様のご支援で成り立っています。もしお役に立てていましたら、ご支援いただけますと大変ありがたいです。

この記事で得られること
✦実行機会の実測ログを取る Swift / Kotlin の最小実装と、そこから読み取れた実行率の傾向
✦「鮮度SLO」として p50 / p90 の経過時間を定義し、コードではなく契約でバックグラウンド更新を語る方法
✦更新が来ない前提で崩れない三層フォールバック設計と、計測をエージェントに委ねる際の境界線
Stripe による安全な決済 · いつでもキャンセル可能
✦

この記事を購入する

この先の内容をすべてお読みいただけます。一度のご購入で、いつでも何度でもアクセスできます。このサイトは広告を掲載しておらず、皆さまのご支援がサーバー費用などの運営を支えています。

または
メンバーシップなら全記事が読み放題 →
シェア

お読みいただきありがとうございます

Antigravity Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • ✦コピー&ペーストで使える実装コード付き
  • ✦毎日新しい上級ガイドを追加
  • ✦¥580/月 または ¥2,480 の永久アクセス
メンバーシップを見る →

関連記事

▣ アプリ開発2026-09-29
Cloudflare をパージしても古い壁紙が届き続けた原因は、オリジン側で JPEG を握っていた XPageSpeed
同じ URL に上書きした壁紙画像が、Cloudflare をパージしても古いまま届き続けた運用の記録です。ローカル・オリジン・エッジの三者を突き合わせて層を名指しする検査、プレフィックスパージの使いどころ、Xserver の XPageSpeed を .htaccess で安全に切る書き方まで扱います。
▣ アプリ開発2026-09-19
見積書 PDF の自動化を一度にまとめて頼み、4 つに割り直すまで
受託の見積書を毎回コピーして作っていた手作業を、Antigravity に頼んで小さな PDF 出力ツールへ移した記録です。最初に全部をまとめて頼んで作り直すことになった理由と、データ・計算・見た目・保存の 4 つに割って渡し直した順番を、動くコードと一緒に書き残します。
▣ アプリ開発2026-09-03
musllinux ホイールが無い依存は、Alpine で失敗せずに遅くなります
Antigravity Python SDK の musllinux ホイール対応を機に、Alpine コンテナで C 拡張が純 Python 実装へ落ちる経路を実測しました。protobuf の直列化は 0.043ms から 36.2ms へ変わります。事前の棚卸しと検知の手順まで書き残します。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます