一、什么是RemoteViews
RemoteViews翻译过来就是远程视图.顾名思义,RemoteViews不是当前进程的View,是属于SystemServer进程.应用程序与RemoteViews之间依赖Binder实现了进程间通信.其主要作用是为了通知和app主体之间进行通信
二、RemoteViews的用法
RemoteViews使用最多的场合是通知栏和桌面小插件. 以通知栏为例,讲解下它的用法.
1实例化一个RemoteViews
RemoteViews mRemoteViews=new RemoteViews("com.example.remoteviewdemo", R.layout.remoteview_layout);
2构建一个打开Activity的PendingIntent
PendingIntent这个类用于处理即将发生的事情,可以理解为延迟执行的intent,PendingIntent是对Intent一个包装
由于pendingintent中 保存有当前App的Context,使它赋予外部App一种能力,使得外部App可以如同当前App一样的执行pendingintent里的 Intent, 就算在执行时当前App已经不存在了,也能通过存在pendingintent里的Context照样执行Intent。另外还可以处理intent执行后的操作。常和alermanger 和notificationmanager一起使用
代码:
Intent intent=new Intent(MainActivity.this,MainActivity.class);
PendingIntent mPendingIntent=PendingIntent.getActivity(
MainActivity.this,requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent 的最后一个参数,4种flag代表的意义
- FLAG_ONE_SHOT 只执行一次
- FLAG_NO_CREATE 若描述的Intent不存在则返回NULL值
- FLAG_CANCEL_CURRENT 如果描述的PendingIntent已经存在,则在产生新的Intent之前会先取消掉当前的
- FLAG_UPDATE_CURRENT 总是执行,这个flag用的最多
3添加到通知
Notification mNotification =newNotification.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentIntent(mPendingIntent)
.setContent(mRemoteViews)
.build();
4.获取NotificationManager
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
5 弹出通知
manager.notify(1, mNotification);
三 改变RemoteViews的布局
RemoteViews并不能直接获得控件实例,然后对控件进行操作.它提供了 以下方法进行交互
- setTextViewText(viewId, text) 设置文本
- setTextColor(viewId, color) 设置文本颜色
- setTextViewTextSize(viewId, units, size) 设置文本大小
- setImageViewBitmap(viewId, bitmap) 设置图片
- setImageViewResource(viewId, srcId) 根据图片资源设置图片
- setViewPadding(viewId,left, top,right, bottom) 设置Padding间距
- setOnClickPendingIntent(viewId, pendingIntent) 设置点击事件
RemoteViews运行在SystemServer进程,更新RemoteViews要通过Binder获取到对应的服务然后调用RemoteViews内部的apply方法加载更新布局.
四、RemoteViews原理
我们的通知和桌面小组件分别是由NotificationManager和AppWidgetManager管理的,而NotificationManager和AppWidgetManager又通过Binder分别和SystemServer进程中的NotificationManagerServer和AppWidgetService进行通信,这就构成了跨进程通信的场景。
RemoteViews实现了Parcelable接口,因此它可以在进程间进行传输。
首先,RemoteViews通过Binder传递到SystemServer进程中,系统会根据RemoteViews提供的包名等信息,去项目包中找到RemoteViews显示的布局等资源,然后通过LayoutInflator去加载RemoteViews中的布局文件,接着,系统会对RemoteViews进行一系列的更新操作,这些操作都是通过RemoteViews对象的set方法进行的,这些更新操作并不是立即执行的,而是在RemoteViews被加载完成之后才执行的,具体流程是:我们调用了set方法后,通过NotificationManager和AppWidgetManager来提交更新任务,然后在SystemServer进程中进行具体的更新操作。
网友评论