1.RemoteViews的作用

在其他进程中显示并更新view界面,所谓跨进程是因为view界面是运行在系统的SystemServer进程的。系统除了常见的notification和appwidget也就是通知栏和桌面小部件,notificatio是通过notificationmanager.notify方法来实现的,appwidget则是通过appwidgetProvider来实现的appwidgetProvider本质上就是个广播。

其实我们也可以通过广播来模拟发送通知栏消息。

2.RemoteViews在通知栏上的应用

2.1典型用法如下,在android8.0以后通知栏的使用有些变化:

Intent intent = new Intent(this, DemoActivity_2.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this,0, intent, PendingIntent.FLAG_ONE_SHOT);
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);int channelId = 0x22222;
Notification.Builder builder;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {NotificationChannel channel = new NotificationChannel(String.valueOf(channelId), "chanel_name", NotificationManager.IMPORTANCE_HIGH);manager.createNotificationChannel(channel);builder = new Notification.Builder(this, String.valueOf(channelId));
} else {builder = new Notification.Builder(this);
}
builder.setContentIntent(pendingIntent);builder.setTicker("new message").setSmallIcon(R.drawable.ic_launcher_background).setContentTitle("标题").setContentText("内容").setContentIntent(pendingIntent);
manager.notify(sId, builder.build());

3.RemoteViews在桌面小部件上的应用

定义桌面小部件也就是remoteviews的布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical" ><ImageViewandroid:id="@+id/imageView1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:src="@drawable/icon1" />
</LinearLayout>

定义桌面小部件配置信息:

<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"android:initialLayout="@layout/widget"android:minHeight="84dp"android:minWidth="84dp"android:updatePeriodMillis="86400000" ><!--initialLayout:初始布局--><!--minHeight + minWidth:尺寸--><!--updatePeriodMillis:更新周期,单位毫秒-->
</appwidget-provider>

桌面小部件实现类:

public class MyAppWidgetProvider extends AppWidgetProvider {public static final String TAG = "MyAppWidgetProvider";public static final String CLICK_ACTION = "com.ryg.chapter_5.action.CLICK";public MyAppWidgetProvider() {super();}@Overridepublic void onReceive(final Context context, Intent intent) {super.onReceive(context, intent);Log.i(TAG, "onReceive : action = " + intent.getAction());// 这里判断是自己的action,做自己的事情,比如小工具被点击了要干啥,这里是做一个动画效果if (intent.getAction().equals(CLICK_ACTION)) {Toast.makeText(context, "clicked it", Toast.LENGTH_SHORT).show();new Thread(new Runnable() {@Overridepublic void run() {Bitmap srcbBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.icon1);AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);for (int i = 0; i < 37; i++) {float degree = (i * 10) % 360;RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget);remoteViews.setImageViewBitmap(R.id.imageView1,rotateBitmap(context, srcbBitmap, degree));appWidgetManager.updateAppWidget(new ComponentName(context, MyAppWidgetProvider.class),remoteViews);SystemClock.sleep(30);}}}).start();}}/*** 最常用的onUpdate方法* 桌面小部件被添加或者更新时,会走到这里*/@Overridepublic void onUpdate(Context context, AppWidgetManager appWidgetManager,int[] appWidgetIds) {super.onUpdate(context, appWidgetManager, appWidgetIds);Log.i(TAG, "onUpdate");final int counter = appWidgetIds.length;Log.i(TAG, "counter = " + counter);for (int i = 0; i < counter; i++) {int appWidgetId = appWidgetIds[i];onWidgetUpdate(context, appWidgetManager, appWidgetId);}}/*** 窗口小部件更新* * @param context* @param appWidgeManger* @param appWidgetId*/private void onWidgetUpdate(Context context,AppWidgetManager appWidgeManger, int appWidgetId) {Log.i(TAG, "appWidgetId = " + appWidgetId);RemoteViews remoteViews = new RemoteViews(context.getPackageName(),R.layout.widget);// "窗口小部件"点击事件发送的Intent广播Intent intentClick = new Intent();intentClick.setAction(CLICK_ACTION);//8.0以上版本必须写intentClick.setComponent(new ComponentName(context,MyAppWidgetProvider.class));PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0,intentClick, 0);remoteViews.setOnClickPendingIntent(R.id.imageView1, pendingIntent);appWidgeManger.updateAppWidget(appWidgetId, remoteViews);}private Bitmap rotateBitmap(Context context, Bitmap srcbBitmap, float degree) {Matrix matrix = new Matrix();matrix.reset();matrix.setRotate(degree);Bitmap tmpBitmap = Bitmap.createBitmap(srcbBitmap, 0, 0,srcbBitmap.getWidth(), srcbBitmap.getHeight(), matrix, true);return tmpBitmap;}

在manifest中声明桌面小部件

<receiver android:name="com.ryg.chapter_5.MyAppWidgetProvider" ><meta-dataandroid: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>

4.notificationId的意义,pengdingIntent需要注意的地方?

4.1notificationId常量与变量

如果notificationId是常量多次调用notify则永远只能弹出一个通知,后面的通知会把前面的通知完全覆盖掉

如果notificationId是变量每次都不同,这时候如果pendingintent不匹配每次的通知是互不干扰的,如果pendingintent匹配(requestcode和intent都相同)这时候就跟pendingintent的标记位有关系了:

4.2pendingintent标志位

FLAG_ONE_SHOT(和第一条通知保持一致)

FALG_CANCEL_CURRENT(只有最新的这条通知可以打开,之前的都是没法打开的)

FLAG_UPDATE_CURRENT(之前的所有通知都会和最新的这一条保持一致)

5.RemoteViews的内部机制,RemoteViews支持哪些view类型,里面的view是怎么赋值的?

notificationmanager和appwidgetmanager通过binder跨进程和systemServer进程中的的notificationmanagerService和appwidgetService进行通信,也就是说remoteview其实是在notificationmanagerService和appwidgetService被加载出来的。当remoteviews调用setText

ViewText等方法的时候,remoteviews中就会添加一个Action对象,最终会形成一个actionList,当remoteviews在systemserver进程中调用apply方法时会遍历actionLsit来更新view。

6.自动模式实现通知栏消息

发送;

RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.layout_simulated_notification);
remoteViews.setTextViewText(R.id.msg, "msg from process:" + Process.myPid());
remoteViews.setImageViewResource(R.id.icon, R.drawable.icon1);
PendingIntent pendingIntent = PendingIntent.getActivity(this,0, new Intent(this, DemoActivity_1.class), PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent openActivity2PendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, DemoActivity_2.class), PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.item_holder, pendingIntent);
remoteViews.setOnClickPendingIntent(R.id.open_activity2, openActivity2PendingIntent);
Intent intent = new Intent(MyConstants.REMOTE_ACTION);
intent.putExtra(MyConstants.EXTRA_REMOTE_VIEWS, remoteViews);
sendBroadcast(intent);

模拟接收:

private BroadcastReceiver mRemoteViewsReceiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {RemoteViews remoteViews = intent.getParcelableExtra(MyConstants.EXTRA_REMOTE_VIEWS);if (remoteViews != null) {updateUI(remoteViews);}}
};private void updateUI(RemoteViews remoteViews) {
//        View view = remoteViews.apply(this, mRemoteViewsContent);int layoutId = getResources().getIdentifier("layout_simulated_notification", "layout", getPackageName());View view = getLayoutInflater().inflate(layoutId, mRemoteViewsContent, false);remoteViews.reapply(this, view);mRemoteViewsContent.addView(view);}

android RemoteViews解析相关推荐

  1. Android RemoteViews 解析

    一.前言 RemoteViews 顾名思义就是远程 View,它表示的是一个 View 结构,它可以在其他进程中显示,为了能跨进程更新它的界面,RemoteViews 提供了一组基础的操作来实现这个效 ...

  2. Android混淆解析

    此文章转载来源https://www.jianshu.com/p/84114b7feb38点击打开链接 Android混淆解析 一.混淆的目的 一款发布到市场的软件原则上都应该做代码混淆. 通过代码混 ...

  3. Android中解析XML

    Android中解析XML 转载于:https://www.cnblogs.com/zhujiabin/p/5868993.html

  4. android 如何实现无限列表,在Android中解析和创建无限/无限级别的List /子列表中的XML...

    在我的Android Application的服务器端应用程序也由我开发.在这个应用程序Android应用程序从服务器请求一些XML并解析它. XML包含描述应用程序中应该有多少标签的信息,并且每个标 ...

  5. 在linux kernel或android中解析cmdline参数

    文章目录 ★★★ 友情链接 : 个人博客导读首页-点击此处 ★★★ Kernel command line: earlycon androidboot.selinux=permissive uart_ ...

  6. android最大json,Android:解析大型JSON文件

    我正在创建一个Android应用程序,该应用程序应该将Json从文件或网址解析为jsonarray和jsonobjects. 问题是,我的JSON是3.3 MB,当我使用一个简单的代码,如下所示:(现 ...

  7. android XMl 解析神奇xstream 六: 把集合list 转化为 XML文档

    前言:对xstream不理解的请看: android XMl 解析神奇xstream 一: 解析android项目中 asset 文件夹 下的 aa.xml 文件 android XMl 解析神奇xs ...

  8. android XMl 解析神奇xstream 五: 把复杂对象转换成 xml ,并写入SD卡中的xml文件

    前言:对xstream不理解的请看: android XMl 解析神奇xstream 一: 解析android项目中 asset 文件夹 下的 aa.xml 文件 android XMl 解析神奇xs ...

  9. android XMl 解析神奇xstream 四: 将复杂的xml文件解析为对象

    前言:对xstream不理解的请看: android XMl 解析神奇xstream 一: 解析android项目中 asset 文件夹 下的 aa.xml 文件 android XMl 解析神奇xs ...

最新文章

  1. Java多线程模式-Balking模式
  2. Java基础-我所理解的泛型
  3. BUUCTF-Reverse:[GKCTF2020]Check_1n
  4. 【NLP】bert4vec:一个基于预训练的句向量生成工具
  5. 过去式加ed的发音_小学英语动词过去式归类总结
  6. win7下注册s2008
  7. python 递归函数与循环的区别_提升Python效率之使用循环机制代替递归函数
  8. 怎么在QQ浏览器上使用微信聊天?
  9. SQL - 18.触发器
  10. php网站服务器500,php服务器错误500
  11. RethinkDB已经将其数据库移植到Windows
  12. hive内部表和外部表的区别_HIVE拉链表实现
  13. PHP框架开发:二、从何处开始?URL
  14. 8. PHP 5 echo 和 print 语句
  15. 吉林大学操作系统概论
  16. java怎么打不开vos_JAVA如何调用VOS2009接口
  17. luajit lua文件加密工具
  18. 【EduCoder答案】时域采样定理
  19. PCI/PCIe硬件相关知识
  20. 自己的小程序修修补补

热门文章

  1. 区块链开发之Metamask使用调研
  2. Minecraft 1.12.2 彩色渐变字体0.2 多重渐变
  3. 登录注册页面,JS判断用户手机号码是否已经存在,或者格式不正确
  4. linux shell grep 非贪婪匹配
  5. javaSE<String和StringBuffer和StringBuider>day11
  6. 计算机安全模式还原系统,Win10电脑安全模式怎么还原系统?Win10电脑安全模式还原系统方法步骤...
  7. Java面向对象设计(面向对象)
  8. Google 推出浏览器版Google Voice
  9. Typora无法在applist里找到
  10. 什么是投入产出比(ROI)以及如何提升投入产出比?