在开发AppWidget时,我们都需要写一个自己的类去继承AppWidgetProvider,本文简单地对AppWidgetProvider的源码进行分析。
首先,AppWidgetProvider继承了BroadcastReceiver,所以本质上它是一个广播接收器,特别地它主要接收由AppWidgetService发送的关于AppWidget的一些广播而已。
其次,它只有一个空的构造方法,并且没有任何成员变量,只有五个方法,当然,其中一个就是onReceive方法,这是它作为广播接收器必须实现的方法。另外四个方法分别是onUpdate、onDeleted、onEnabled和onDisabled,但是这四个方法体都是空的,用户继承了AppWidgetProvider可以自己实现这些方法作想做的事。
关键我们来看onReceive方法。首先附上源码,再对其进行分析。
public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) { Bundle extras = intent.getExtras(); if (extras != null) { int[] appWidgetIds = extras.getIntArray(AppWidgetManager.EXTRA_APPWIDGET_IDS); if (appWidgetIds != null && appWidgetIds.length > 0) { this.onUpdate(context, AppWidgetManager.getInstance(context), appWidgetIds); } } } else if (AppWidgetManager.ACTION_APPWIDGET_DELETED.equals(action)) { Bundle extras = intent.getExtras(); if (extras != null && extras.containsKey(AppWidgetManager.EXTRA_APPWIDGET_ID)) { final int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID); this.onDeleted(context, new int[] { appWidgetId }); } } else if (AppWidgetManager.ACTION_APPWIDGET_ENABLED.equals(action)) { this.onEnabled(context); } else if (AppWidgetManager.ACTION_APPWIDGET_DISABLED.equals(action)) { this.onDisabled(context); } }
代码其实非常简单,对接收到的Intent提取出它携带的Action,然后根据Action的不同,分别调用自己的四个方法。四个Action在AppWidgetManager中定义如下:
public static final String ACTION_APPWIDGET_UPDATE = "android.appwidget.action.APPWIDGET_UPDATE"; public static final String ACTION_APPWIDGET_DELETED = "android.appwidget.action.APPWIDGET_DELETED"; public static final String ACTION_APPWIDGET_DISABLED = "android.appwidget.action.APPWIDGET_DISABLED"; public static final String ACTION_APPWIDGET_ENABLED = "android.appwidget.action.APPWIDGET_ENABLED";
还有一些问题需要说明一下:1.谁会发送广播给AppWidgetProvider;2.什么时候发送广播;3.为何我们在Manifest.xml中只注册了一个Action: android.appwidget.action.APPWIDGET_UPDATE,却可以接收四种广播。下面是Manifest.xml的一部分,可以看到在 intent-filter 中只有一个Action:
<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>