《Android艺术探索》读书笔记 第五章. RemoteViews

RemoteView应用

  • 跨进程更新界面,widget和notification都运行在SystemServer进程中

  • 单击事件一般通过PendingIntent发广播的方式来实现

  • onEanble()只在第一次添加回调,onDeleted()删除一次回调一次,onDisable()最后一个删除时回调,onUpdate()每次添加或更新时回调

PendingIntent

  • PendingIntent是即刻发生,Intent是立刻发生.典型场景还是RemoteViews的单机事件

  • PendingIntent支持三种待定意图:启动Activity(getActivity),启动Service(getService),发送广播(getBroadcast)

  • PendingIntent 的requestCode相同并且Intent也相同,则证明PendingIntent相同,Intent相同则需要ComponentName和intent-filter相同。

  • PendingIntent 中flags

    • FLAG_ONE_SHOT:同类通知只能使用一次,后续单机打开无效
    • FLAG_NO_CREATE:没意义
    • FLAG_CANCEL_CURRENT: 如果PendingIntent已经存在,都会被cancle,系统创建一个新的,那些被cancel了的将无法打开
    • FLAG_UPDATE_CURRENT: 如果PendingIntent已经存在,它们都会被更新,Intent中的Extras被替换成最新的
  • 分析NotificationManager.nofify(id, notification) [未测试,看着有点晕]

    • 如果参数id是常量,那么多次调用notify只能弹出一个通知,后续的通知会把前面的通知完全替代掉;

    • 如果参数id每次都不同,那么当PendingIntent不匹配的时候,不管采用何种标志位,这些通知之间不会相互干扰;

    • 如果参数id每次都不同,且PendingIntent匹配的时候,那就要看标志位:

RemoteView内部机制

  • 通知栏和widget布局文件实际上是在NotificationManagerService和AppWidgetService被加载,运行在SystemServer进程中,系统首先将view操作封装到action对象中,并将这些对象跨进程传输到远程进程,远程进程通过RemoteViews的apply方法进行View的更新操作,apply方法会遍历所有action对象来调用它们的apply方法

  • 无法使用自定义View,EditText不支持在RemoteView中使用

  • RemoteViews实现了Parcelable接口,它会通过Binder传递到SystemServer进程,系统会根据RemoteViews中的包名信息获取到应用中的资源,从而完成布局文件的加载

  • 系统将view操作封装成Action对象,Action同样实现了Parcelable接口,通过Binder传递到SystemServer进程。远程进程通过RemoteViews的apply方法来进行view的更新操作,RemoteViews的apply方法内部则会去遍历所有的action对象并调用它们的apply方法来进行view的更新操作。这样做的好处是不需要定义大量的Binder接口,其次批量执行RemoteViews中的更新操作提高了程序性能。

  • RemoteView的大部分方法都是通过set反射完成

  • RemoteView中,apply加载布局更新界面,reApply只会更新界面

  • setOnClickPendingIntent用于普通view设置单机事件,setPendingIntentTemplate和setOnClickFillInIntent组合使用用于ListView的item点击事件

RemoteView特例

  • 在两个应用中,用广播的方式完成跨进程通信,通过intent传递remoteviews,来更新另外一个进程的UI,当然RemoteView只能支持一些简单的view。

当前网速较慢或者你使用的浏览器不支持博客特定功能,请尝试刷新或换用Chrome、Firefox等现代浏览器