理解RemoteViews(Android开发艺术探索读书笔记)

来源:互联网 发布:数控火焰切割手动编程 编辑:程序博客网 时间:2024/06/05 08:44

RemoteView在通知栏上的应用
Notification

RemoteViews在桌面小部件上的应用

AppWidgetProvider(继承自BroadcastReceiver)
组件代码声明

  <receiver android:name=".MyAppWidgetProvider" >            <meta-data                android:name="android.appwidget.provider"                android:resource="@xml/appwidget_provider_info" >            </meta-data>            <intent-filter>                <action android:name="com.ryg.chapter_5.action.CLICK" />                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />            </intent-filter>        </receiver>

上面代码中有两个Action,其中第一个Action用于识别小部件的单击行为,而第二个Action则作为小部件的标识而必须存在,这是系统的规范,如果不加,那么这个receiver就不是一个桌面小部件并且也无法出现在手机的小部件列表里面。

常用回调:

  • onEnable: 当该窗口小部件第一次添加桌面时调用该方法,可添加多次但只在第一次调用。
  • onUpdate:小部件被添加时或者每次小部件更新时都会调用一次方法,小部件的更新时机由updatePeriodMillis来指定,每个周期小部件都会自动更新一次。
  • onDelete:每次删除一次桌面小部件调用一次
  • onDisabled:当最后一个该类型的桌面小部件被删除时调用该方法,注意是最后一个。
  • onReceive:这是广播的内置方法,用于分发具体的事件给其他方法。

PendingIntent概述

PendingIntent表示一种处于pending状态的意图,而pending状态表示的是一种待定,等待,即将发生的意思,就是说接下来有一个Intent将在某个待定的时刻发生。

static PendingIntent getActivity(Context context,int requestCode,Intent intent,int flags )

requestCode:表示PendingIntent发送方的请求码,多数情况设为0 即可,另外,requestCode会影响到flags的效果。

PendingIntent匹配规则:如果两个PendingInten它们内部的Intent相同并且requestCode也相同,那么这两个PendingIntent就是相同的。

Intent匹配规则:如果两个Intent的ComponentName和intent-filter都相同,那么这两个Intent就是相同的。需要注意,Extras不参与Intent的匹配过程。

flags:

  • FLAG_ONE_SHOT 当前描述的PendingIntent只能被使用一次,然后它就会被自动cancel,如果后续还有相同的PendingIntent,那么它们的send方法就会调用失败。对于通知栏消息来说,如果采用此标记位,那么同类的通知只能使用一次,后续的通知单击后将无法打开。
  • FLAG_NO_CREATE 当前的描述的PendingIntent不会主动创建,如果当前PendingIntent之前不存在,那么getActivity,getService,getBroadcase方法会直接返回null,即获取PendingIntent失败。这个标记位很少见,它无法单独使用,因此在日常开发中它并没头太多的使用意义,这里就不再过多介绍。
  • FLAG_CANCEL_CURRENT 当前描述的PendingIntent如果已经存在,那么它们都会被cancel,然后系统会创建一个新的PendingIntent,对于通知栏消息来说,那些被cancel的消息单击后将无法打开。
  • FLAG_UPDATE_CURRENT 当前描述的PendingIntent如果已经存在,那么它们都会被更新,即它们的Intent中的Extras会被替换成最新的。

RemoteViews的内部机制

我们知道,通知栏和桌面小部件分别NotificationManager和AppWidgetManager管理,而NotificationManager和AppWidgetManager通过Binder分别 和SystemServer进程中的NotificationManagerService以及AppWidgetService进行通信。由此可见,通知栏和桌面小部件的布局文件实际上是在NotificationManagerService以及AppWidgetService中被加载的,而它们运行在SystemService中,这就和我们的进程构成了跨进程通信的情景。

由于View内部方法太多,系统没有通过Binder 去直接支持View的跨进程访问,而是提供一个Action的概念。在我们的应用中每调用一次set方法,RemoteViews中就会添加一个对应的Action对象。并通过NotificationManager和AppWidgetManager来提交我们的更新,然后远程进程通过RemoteViews的apply方法来进行View的更新操作,RemoteViews的apply的方法内部则会去遍历所有的Action对象调用它们的Action.apply方法,具体的View更新操作是由Action对象的apply方法来完成的。这样避免了大量的IPC操作。

这里写图片描述

注意几点:

apply和reApply的区别:apply会加载布局并更新界面,而reApply则只会更新界面。

各种Action的子类对应不同的View一系列的方法

关于单击事件,RemoteViews中只支持发起PendingIntent,不支持onClickListener那种模式,要用setOnClickPendingIntent.其次,如果要给ListView和StackView中的item添加单击事件,则必须将setPendingIntentTamplate和setOnClickFillInIntent组合使用才可以。

RemoteViews的意义:
考虑跨进程更新View的情况,利用AIDL理论上没问题,但大量的IPC会有效率问题。RemoteViews避免了这种问题,但只支持一些常见的View,对于自定义View它是不支持的。

0 0
原创粉丝点击