このページでは、より高度なウィジェットを作成するためのおすすめの方法について説明します。 ユーザーエクスペリエンスが向上します
ウィジェット コンテンツの更新の最適化
ウィジェットのコンテンツを更新すると、計算コストが高くなる可能性があります。バッテリーを節約するため 更新の種類、頻度、タイミングを最適化します。
ウィジェットの更新の種類
ウィジェットを更新する方法には、完全な更新、部分更新、 データを更新しますそれぞれに異なる 影響を及ぼします
以下では、各更新タイプについて説明し、それぞれのコード スニペットを示します。
フル アップデート:
AppWidgetManager.updateAppWidget(int, android.widget.RemoteViews)
を呼び出します。 ウィジェットを完全に更新します。これは、以前に指定した 新しいRemoteViews
RemoteViews
。これは最も計算コストの高い更新です。Kotlin
val appWidgetManager = AppWidgetManager.getInstance(context) val remoteViews = RemoteViews(context.getPackageName(), R.layout.widgetlayout).also { setTextViewText(R.id.textview_widget_layout1, "Updated text1") setTextViewText(R.id.textview_widget_layout2, "Updated text2") } appWidgetManager.updateAppWidget(appWidgetId, remoteViews)
Java
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context); RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widgetlayout); remoteViews.setTextViewText(R.id.textview_widget_layout1, "Updated text1"); remoteViews.setTextViewText(R.id.textview_widget_layout2, "Updated text2"); appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
部分更新: 呼び出し
AppWidgetManager.partiallyUpdateAppWidget
ウィジェットの一部を更新したりできますこれにより、新しいRemoteViews
が 以前に指定したRemoteViews
。このメソッドは、ウィジェットがupdateAppWidget(int[], RemoteViews)
を通じてフル アップデートを 1 回以上受信していない。Kotlin
val appWidgetManager = AppWidgetManager.getInstance(context) val remoteViews = RemoteViews(context.getPackageName(), R.layout.widgetlayout).also { setTextViewText(R.id.textview_widget_layout, "Updated text") } appWidgetManager.partiallyUpdateAppWidget(appWidgetId, remoteViews)
Java
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context); RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widgetlayout); remoteViews.setTextViewText(R.id.textview_widget_layout, "Updated text"); appWidgetManager.partiallyUpdateAppWidget(appWidgetId, remoteViews);
コレクション データの更新: 呼び出し
AppWidgetManager.notifyAppWidgetViewDataChanged
ウィジェットのコレクション ビューのデータを無効化できます。トリガーRemoteViewsFactory.onDataSetChanged
。 それまでの間、古いデータがウィジェットに表示されます。安全に コストの高いタスクをこのメソッドと同期して実行します。Kotlin
val appWidgetManager = AppWidgetManager.getInstance(context) appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.widget_listview)
Java
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context); appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.widget_listview);
これらのメソッドは、
同じ UID を
AppWidgetProvider
クラス。
ウィジェットを更新する頻度を決定する
ウィジェットは、
updatePeriodMillis
属性です。ウィジェットは、ユーザーの操作、ブロードキャスト、
実行できます。
定期的に更新する
定期的な更新の頻度を制御するには、
appwidget-provider
XML 内の AppWidgetProviderInfo.updatePeriodMillis
。各
update は AppWidgetProvider.onUpdate()
メソッドをトリガーします。
ウィジェットを更新するコードを配置できますただし、別の仮想マシン(VM)に
ブロードキャスト レシーバの更新が記述され、
ウィジェットでデータを非同期で読み込む必要がある場合や、
更新に 10 秒はかかります。10 秒が経過すると、システムは更新に
BroadcastReceiver
は、応答しなくなります。
updatePeriodMillis
は 30 分未満の値に対応していません。ただし、
定期的な更新を無効にする場合は、0 を指定します。
管理者は、ユーザーが構成の更新頻度を調整できるようにすることができます。対象
たとえば、株式相場を 15 分ごとや 4 分の 1 ごとに
です。この場合、updatePeriodMillis
を 0 に設定して、
WorkManager
をご利用ください。
ユーザーの操作に応じて更新する
ユーザーの操作に応じてウィジェットを更新するためのおすすめの方法を以下に示します。
アプリのアクティビティから: 直接呼び出します。
AppWidgetManager.updateAppWidget
のようなユーザー インタラクション( 認識できます。通知やアプリ ウィジェットなどのリモート操作から:
PendingIntent
を作成してから、呼び出された場所からウィジェットをActivity
、Broadcast
、Service
。優先度はご自身で選択できます。対象 たとえば、PendingIntent
にBroadcast
を選択した場合、 フォアグラウンド ブロードキャストを使用して、 優先度BroadcastReceiver
。
ブロードキャスト イベントに応じて更新する
ウィジェットの更新が必要なブロードキャスト イベントの例として、 ユーザーが写真を撮影します。この場合は、新しい写真が追加されたときにウィジェットを 検出されます。
JobScheduler
でジョブをスケジュールし、ブロードキャストを
使用してトリガーします。
JobInfo.Builder.addTriggerContentUri
メソッドを呼び出します。
ブロードキャストの BroadcastReceiver
を登録することもできます。次に例を示します。
待機中
ACTION_LOCALE_CHANGED
。
ただし、デバイスのリソースを消費するため、慎重に使用し、リッスンしてください
特定のブロードキャストのみに限定できますブロードキャストの導入により、
Android の制限事項
7.0(API レベル 24)と Android 8.0(API レベル 26)では、アプリは暗黙的に
ブロードキャストをマニフェスト内で使用し、特定の
例外があります。
BroadcastReceiver からウィジェットを更新する際の考慮事項
ウィジェットが以下を含む BroadcastReceiver
から更新された場合
AppWidgetProvider
の使用に関して、次の考慮事項に留意してください。
ウィジェットの更新の所要時間と優先度です
更新の期間
原則として、ブロードキャスト レシーバは、通常はアプリの 最大 10 秒間実行した後で、そのスレッドは応答しないと見なされ、 Application Not 応答中(ANR)エラー。テストの実施に 次の方法を検討してください。
WorkManager
を使用してタスクのスケジュールを設定します。メッセージで応答時間を長くする
goAsync
メソッドを使用します。 これにより、レシーバーは 30 秒間実行できます。
セキュリティに関する考慮事項とベスト プラクティスを プラクティスをご覧ください。 情報です。
アップデートの優先度
デフォルトでは、ブロードキャスト(
AppWidgetProvider.onUpdate
- バックグラウンド プロセスとして実行します。つまり
システム リソースが過負荷状態になると、ブロードキャストの呼び出しが遅延する可能性がある
受信します。ブロードキャストを優先するには、フォアグラウンド プロセスにします。
たとえば、
Intent.FLAG_RECEIVER_FOREGROUND
PendingIntent.getBroadcast
に渡される Intent
にフラグを
ウィジェットの特定の部分をタップしたときに
通知を受け取ることができます
動的アイテムを含む正確なプレビューを作成する
<ph type="x-smartling-placeholder">このセクションでは、
コレクションを含むウィジェットのウィジェット プレビュー
ビューがあります。つまり、
ListView
、GridView
、または StackView
。
ウィジェットでこれらのビューのいずれかを使用している場合、直接 実際のウィジェットを レイアウトによって ウィジェットのプレビューにアイテムが表示されない場合があります。これは次の理由で発生します。 コレクション ビューのデータは実行時に動的に設定され、 図 1 に示します。
コレクション ビューを含むウィジェットのプレビューがウィジェット内で正しく表示されるようにする
専用のレイアウト ファイルを
プレビューします。この個別のレイアウト ファイルには、実際のウィジェット レイアウトと、
架空のアイテムを含むプレースホルダ コレクション ビュー。たとえば、Python や Curl など、
ListView
(プレースホルダ LinearLayout
といくつかの架空のリストを指定)
あります。
ListView
の例を示すために、別のレイアウト ファイルから始めます。
// res/layout/widget_preview.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/widget_background"
android:orientation="vertical">
// Include the actual widget layout that contains ListView.
<include
layout="@layout/widget_view"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
// The number of fake items you include depends on the values you provide
// for minHeight or targetCellHeight in the AppWidgetProviderInfo
// definition.
<TextView android:text="@string/fake_item1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginVertical="?attr/appWidgetInternalPadding" />
<TextView android:text="@string/fake_item2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginVertical="?attr/appWidgetInternalPadding" />
</LinearLayout>
次の previewLayout
属性を指定する場合は、プレビュー レイアウト ファイルを指定します。
AppWidgetProviderInfo
メタデータ。実際のウィジェット レイアウトは、引き続き指定します。
initialLayout
属性用とし、場合は実際のウィジェット レイアウトを使用します。
実行時に RemoteViews
を作成します。
<appwidget-provider
previewLayout="@layout/widget_previe"
initialLayout="@layout/widget_view" />
複雑なリストアイテム
前のセクションの例では、架空のリストアイテムを使用しています。
アイテムは TextView
オブジェクトです。かもしれない
アイテムが複雑なレイアウトの場合、架空のアイテムを提供するのはより複雑になります。
widget_list_item.xml
で定義され、次の要素で構成されるリストアイテムについて考えてみましょう。
2 つの TextView
オブジェクト:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView android:id="@id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/fake_title" />
<TextView android:id="@id/content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/fake_content" />
</LinearLayout>
架空のリストアイテムを提供するには、レイアウトを複数回インクルードできますが、 各リスト項目が同一になります。固有のリストアイテムを指定するには、 手順は次のとおりです。
テキスト値の属性セットを作成します。
<resources> <attr name="widgetTitle" format="string" /> <attr name="widgetContent" format="string" /> </resources>
次の属性を使用してテキストを設定します。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content"> <TextView android:id="@id/title" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="?widgetTitle" /> <TextView android:id="@id/content" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="?widgetContent" /> </LinearLayout>
プレビューに必要な数のスタイルを作成します。Deployment の 各スタイル:
<resources> <style name="Theme.Widget.ListItem"> <item name="widgetTitle"></item> <item name="widgetContent"></item> </style> <style name="Theme.Widget.ListItem.Preview1"> <item name="widgetTitle">Fake Title 1</item> <item name="widgetContent">Fake content 1</item> </style> <style name="Theme.Widget.ListItem.Preview2"> <item name="widgetTitle">Fake title 2</item> <item name="widgetContent">Fake content 2</item> </style> </resources>
プレビュー レイアウトの架空のアイテムにスタイルを適用します。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" ...> <include layout="@layout/widget_view" ... /> <include layout="@layout/widget_list_item" android:theme="@style/Theme.Widget.ListItem.Preview1" /> <include layout="@layout/widget_list_item" android:theme="@style/Theme.Widget.ListItem.Preview2" /> </LinearLayout>