探秘widget之widget背后的故事

                               By 何明桂(http://blog.csdn.net/hmg25) 转载请注明出处

 

     之前分析了下widget添加到laucher的过程,现在我们来分析下widget被添加到laucher之后发生的故事。

     AppWidgetProvider

 

桌面组件实现的组要类,它的父类是一个广播接收器,它主要作用就是接收更新桌面组件的广播消息,然后更新桌面组件

                         i.              public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds)

该方法对应事件:android.appwidget.action.APPWIDGET_UPDATE当桌面组件被周期更新的时候它被调用,深入父类的onReceive方法就会了解到,当父类的onReceive方法接收到android.appwidget.action.APPWIDGET_UPDATE消息就会调用该update方法。

                       ii.              public void onReceive(Context context, Intent intent)

AppWidgetProvider本身是一个广播接收器,父类已经覆盖了该方法,你重新覆盖该方法的时候,注意要添加super. onReceive到你的方法中,否则onUpdate将不再会被调用

                      iii.              public void onDeleted(Context context, int[] appWidgetIds)

AppWidgetProvider接收消息android.appwidget.action.APPWIDGET_DELETED时候调用该方法。

 

 

每个桌面组件就是一个AppWidget,当你需要在代码中实现一个桌面组件,首先你必须得实现AppWidgetProvider类,当你点击AppWidgetProvider类你会发现其实AppWidgetProvider就是一个BroadcastReceiver子类,也就是说它也是一个广播接收器。桌面组件内容显示更新全部是通过RemoteViews对象,刚创建桌面组件的时候系统会绑定AppWidgetProvider到一个AppWidgetId,然后后面通过AppWidgetManager.updateAppWidget方法把RemoteViews对象更新到对应的桌面组件。

 

     回到之前添加widget时的流程,在桌面组件刚被添加的时候,系统通过AppWidgetHost.allocateAppWidgetId函数为桌面组件分配一个新的AppWidgetId。在选择widget的时候,通过点击的列表选项可获取到对应桌面组件对应的ComponentName,一个ComponentName由一个包名和一个AppWidgetProvider类名称唯一指定,然后通过AppWidgetManager.bindAppWidgetId(int appWidgetId, ComponentName provider)把前面生成的AppWidgetId与一个ComponentName绑定,一个ComponentName可以绑定多个AppWidgetId。所以你可以在桌面上放置几个一样的widget。

      一个AppWidgetProvider可以由一个ComponentName唯一确定,在一般的widget应用中:

 

 

每一个AppWidgetProvider上可能建立了多个桌面组件,每一个桌面组件对以应一个AppWidgetId,要获取一个AppWidgetProvider上所有的桌面组件的AppWidgetId数据,可以先建一个ComponentName对象,设置ComponentName中的类名和包名为AppWidgetProvider的类名和包名,然后可通过AppWidgetManager. getAppWidgetIds(ComponentName provider)方法获取AppWidgetId列表。

通过AppWidgetId我们便可以操作指定的widget。

    widget界面的更新是通过RemoteViews日哦,而RemoteViews并不是一个真正的View,它没有实现View的接口,而只是一个用于描述View的实体。比如:创建View需要的资源ID和各个控件的事件响应方法。RemoteViews会通过进程间通信机制传递给AppWidgetHost。

    AppWidgetHost和AppWidgetHostView是在framework中定义的两个基类。应用程序可以利用这两个类来实现自己的Host。Launcher是缺省的桌面,它是一个Host的实现者。

LauncherAppWidgetHostView扩展了AppWidgetHostView,实现了对长按事件的处理。

LauncherAppWidgetHost扩展了AppWidgetHost,这里只是重载了onCreateView,创建LauncherAppWidgetHostView的实例。

     Remoteviews更新桌面组件最终还是要在launcher进程中执行,在launcher中有一个handler: AppWidgetHost.UpdateHandler,该handler就是用来处理Remoteviews更新的,一旦我们调用appWidgetManager.updateAppWidget(appWidgetId, views)这个方法,AppWidgetHost.UpdateHandler. handleMessage事件就会响应,不过要注意是该事件响应是在launcher进程中执行:

 

 

 

 

 

 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值