最近项目中接触到AppWidget,相对来说这部分比较简单,所以趁着空余时间详细阅读了AppWidget的源码。这篇文章主要是从源码上分析AppWidget中API类的相关原理,相关类的简单功能介绍和实现原理。关于使用,建议看指导文档。
简述
AppWidget相关的API类(供我们应用开发者使用的类)主要有:
AppWidgetProvider:继承这个类,来提供Appwidget。
AppWidgetManager:提供了AppWidget的管理接口,比如更新,绑定AppWidget id,根据Component获取AppWidget id等等。
RemoteView:能够跨进程更新的View。
AppWidgetHost:与AppWidgt 服务交互的类,获取App widget,显示出来
AppwidgetHostView:实际上显示出来的View
他们之间的关系简略来讲如下:
AppWidget Service 是一些类的集合,是AppWidget的核心服务,在之后的文章会介绍,这篇就不介绍了。下面详细介绍每个类的功能以及实现原理。
AppWidgetProvider
这是我们在建立AppWidget的时候,需要去实现的类,它有几个重要的方法:
public void onAppWidgetOptionsChanged(Context context, AppWidgetManager appWidgetManager,
int appWidgetId, Bundle newOptions) // 当Widget的布局到新的大小的时候会被调用
public void onDeleted(Context context, int[] appWidgetIds) // 当某个Widget被移除的时候回调
public void onDisabled(Context context) // 当最后一个Widget被移除的时候回调
public void onEnabled(Context context) // 当第一个Widget被添加的时候回调
public void onRestored(Context context, int[] oldWidgetIds, int[] newWidgetIds) // 当Widget从缓存的Widget恢复时
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) //当Widget需要被提供RemoteView的时候,每次添加Widget的时候会调用
public void onReceive(Context context, Intent intent) // 后面介绍
这几个方法是我们在继承AppWidgetProvider的时候,可以根据自己的需要来实现的方法。注释里面是每个方法被回调的时机。
实际上如果去查看AppWidgetProvider的源码,你会发现AppWidgetProvider是继承自BroadcastReceiver的,也就是说它是一种广播。所以它也有一个onReceive方法,这个方法我前面特意没有说明什么时候调用,其实就是收到广播的时候回调。看看onReceive方法的实现,你会发现前面的那几个方法都是在onReceiver中调用的,每一种方法都对应着一种广播Action:
public void onReceive(Context context, Intent intent) {
// Protect against rogue update broadcasts (not really a security issue,
// just filter bad broacasts out so subclasses are less likely to crash).
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