App Widget 是 Android 中的一种微型应用视图,可以嵌入到其他应用(如桌面 Home Screen)中,并支持周期性更新。最常见的例子就是桌面 Widget,比如天气小部件、音乐播放器控件等。

基本架构#
一个 App Widget 由以下组件构成:
- AppWidgetProviderInfo:定义 Widget 的元数据(布局、更新频率、尺寸等),在 XML 中声明
- AppWidgetProvider:继承自 BroadcastReceiver,处理 Widget 的生命周期事件
- View Layout:Widget 的界面布局,使用 RemoteViews 构建
关键生命周期方法#
| 方法 | 触发时机 |
|---|
onUpdate() | 到达更新周期时触发,是唯一必须实现的方法 |
onAppWidgetOptionsChanged() | Widget 尺寸变化时触发 |
onEnabled(Context) | 第一个 Widget 实例被创建时触发 |
onDisabled(Context) | 最后一个 Widget 实例被移除时触发 |
onDeleted(Context, int[]) | Widget 实例被删除时触发 |
创建步骤#
res/xml/example_appwidget_info.xml:
1
2
3
4
5
6
7
| <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="250dp"
android:minHeight="40dp"
android:updatePeriodMillis="86400000"
android:initialLayout="@layout/example_appwidget"
android:resizeMode="horizontal|vertical"
android:widgetCategory="home_screen" />
|
2. 创建布局#
Widget 布局使用 RemoteViews,支持的控件有限(主要是 FrameLayout、LinearLayout、RelativeLayout、GridLayout、Button、TextView、ImageView 等):
res/layout/example_appwidget.xml:
1
2
3
4
5
6
7
8
9
10
11
| <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:id="@+id/example_text"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="Hello Widget!" />
</LinearLayout>
|
3. 实现 Provider#
1
2
3
4
5
6
7
8
9
10
11
| public class ExampleAppWidgetProvider extends AppWidgetProvider {
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
for (int appWidgetId : appWidgetIds) {
RemoteViews views = new RemoteViews(
context.getPackageName(), R.layout.example_appwidget);
views.setTextViewText(R.id.example_text, "Updated!");
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
}
|
4. 在 AndroidManifest 中声明#
1
2
3
4
5
6
7
8
| <receiver android:name=".ExampleAppWidgetProvider">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/example_appwidget_info" />
</receiver>
|
局限性#
- Widget 不能使用自定义 View 或 View 子类——只能使用 RemoteViews 支持的控件
- Widget 的更新频率由系统管理,
updatePeriodMillis 最小值为 30 分钟 - 使用 ListView 或 GridView 时需要配合 RemoteViewsService 提供数据