理解RemoteViews————读书笔记
来源:互联网 发布:kk源码网 编辑:程序博客网 时间:2024/06/04 01:22
理解RemoteViews
RemoteViews的应用
RemoteViews在实际开发中主要用于通知栏和桌面小部件。
RemoteViews在通知栏上的应用
Notification notification = new Notification(); notification.icon = R.drawable.ic_launcher; notification.tickerText = "hello world"; notification.when = System.currentTimeMillis(); notification.flags = Notification.FLAG_AUTO_CANCEL; Intent intent = new Intent(this, DemoActivity_1.class); intent.putExtra("sid", "" + sId); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); System.out.println(pendingIntent); RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.layout_notification); remoteViews.setTextViewText(R.id.msg, "chapter_5: " + sId); remoteViews.setImageViewResource(R.id.icon, R.drawable.icon1); PendingIntent openActivity2PendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, DemoActivity_2.class), PendingIntent.FLAG_UPDATE_CURRENT); remoteViews.setOnClickPendingIntent(R.id.open_activity2, openActivity2PendingIntent); notification.contentView = remoteViews; notification.contentIntent = pendingIntent; NotificationManager manager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE); manager.notify(sId, notification);
只要提供当前应用的包名和布局文件的资源ID即可创建一个RemoteViews对象。更新RemoteViews只能使用setTextViewText, setImageViewResource, setOnClickPendingIntent等固定方法来设置View,不能像操作普通View的方式来操作。
RemoteViews在桌面小部件上的应用
AppWidgetProvider是Android中提供的用于实现桌面小部件的类,其本质是一个广播,即继承了BroadcastReceiver.
APPWidgetProvider的开发步骤:定义界面xml,定义配置信息xml,定义实现类(继承AppWidgetProvider),AndroidManifest中声明。
重要回调:onEnable,第一次被添加时调用,只有一次;onUpdate,添加或更新时回调;onDelete,每次删除时回调;onDisable,最后一次删除时回调;onReceive,接收广播的action。
PendingIntent
PendingIntent表示接下来有一个Intent将在某个待定的时刻发生。
1.典型的使用场景就是和RemoteViews的点击事件配合使用;
2.支持三种待定Intent:Activity,Service和Broadcast,主要方法:getActicity、getService、getBroadcast
3.PendingIntent相同的定义:内部的Intent和requestCode都相同。Intent相同的定义:两个Intent的componentName和intent-filter相同(不包括extras)
4.flag定义:FLAG_NO_CREATE,如果当前得PendingIntent之前不存在,那么getActicity、getService、getBroadcast方法直接返回null,即获取PendingIntent失败;FLAG_ONE_SHOT,以第一个为准,后续的会全部和第一条保持一致,任意一条被触发,其他的都cancel;FLAG_CANCEL_CURRENT,前面的相同的PendingIntent都会被cancel,只有最新的可用;FLAG_UDPATE_CURRENT,前面的PendingIntent都会被更新(它们Intent中的extras都会被更新)
RemoteViews的内部机制
1.RemoteViews的作用是在其他进程中显示并更新View界面,支持的View类型:Layout:FrameLayout, LinearLayout, RelativeLayout, GridLayout; View: AnalogClock, Button, Chronometer, ImageButton, ImageView, ProgressBar, TextView, ViewFlipper, ListView, GridView, StackView, AdapterViewFlipper, ViewStub。
2.源码分析:
RemoteViews#setBitmap
public void setBitmap(int viewId, String methodName, Bitmap value) { addAction(new BitmapReflectionAction(viewId, methodName, value));}
RemoteViews#addAction
private void addAction(Action a) { if (hasLandscapeAndPortraitLayouts()) { throw new RuntimeException("RemoteViews specifying separate landscape and portrait" + " layouts cannot be modified. Instead, fully configure the landscape and" + " portrait layouts individually before constructing the combined layout."); } if (mActions == null) { mActions = new ArrayList<Action>(); } mActions.add(a); // update the memory usage stats a.updateMemoryUsageEstimate(mMemoryUsageCounter); }
RemoteViews#apply
/** @hide */public View apply(Context context, ViewGroup parent, OnClickHandler handler) { RemoteViews rvToApply = getRemoteViewsToApply(context); View result; // RemoteViews may be built by an application installed in another // user. So build a context that loads resources from that user but // still returns the current users userId so settings like data / time formats // are loaded without requiring cross user persmissions. final Context contextForResources = getContextForResources(context); Context inflationContext = new ContextWrapper(context) { @Override public Resources getResources() { return contextForResources.getResources(); } @Override public Resources.Theme getTheme() { return contextForResources.getTheme(); } @Override public String getPackageName() { return contextForResources.getPackageName(); } }; LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); // Clone inflater so we load resources from correct context and // we don't add a filter to the static version returned by getSystemService. inflater = inflater.cloneInContext(inflationContext); inflater.setFilter(this); result = inflater.inflate(rvToApply.getLayoutId(), parent, false); rvToApply.performApply(result, parent, handler); return result;}
RemoteViews#ReflectionAction extends Action#apply
@Override public void apply(View root, ViewGroup rootParent, OnClickHandler handler) { final View view = root.findViewById(viewId); if (view == null) return; Class<?> param = getParameterType(); if (param == null) { throw new ActionException("bad type: " + this.type); } try { getMethod(view, this.methodName, param).invoke(view, wrapArg(this.value)); } catch (ActionException e) { throw e; } catch (Exception ex) { throw new ActionException(ex); } }
RemoteViews#TextViewSizeAction extends Action
private class TextViewSizeAction extends Action { public TextViewSizeAction(int viewId, int units, float size) { this.viewId = viewId; this.units = units; this.size = size; } public TextViewSizeAction(Parcel parcel) { viewId = parcel.readInt(); units = parcel.readInt(); size = parcel.readFloat(); } public void writeToParcel(Parcel dest, int flags) { dest.writeInt(TAG); dest.writeInt(viewId); dest.writeInt(units); dest.writeFloat(size); } @Override public void apply(View root, ViewGroup rootParent, OnClickHandler handler) { final TextView target = (TextView) root.findViewById(viewId); if (target == null) return; target.setTextSize(units, size); } public String getActionName() { return "TextViewSizeAction"; } int units; float size; public final static int TAG = 13; }
简单归纳,客户端的RemoteViews通过binder机制来传递到SystemServer进程,(RemoteViews本身也实现了Parcelable接口)。本地进程的View操作(一系列的set方法)都转化成一系列的Action对象,远程进程通过Action对象的apply方法就是真正操作View的地方。方法apply和reapply,前者会加载布局并更新界面,后者则只更新界面。
- 理解RemoteViews————读书笔记
- 读书笔记--理解RemoteViews
- 读书笔记(5) 理解RemoteViews
- Android开发艺术探索第五章——理解RemoteViews
- 理解RemoteViews
- 理解RemoteViews
- 理解RemoteViews
- 理解RemoteViews
- Android开发艺术探索 第5章 理解RemoteViews 读书笔记
- 理解RemoteViews(Android开发艺术探索读书笔记)
- 读书笔记——深入理解虚拟机
- 读书笔记——深入理解java虚拟机
- 深入理解 RemoteViews
- 第五章 理解RemoteViews
- 理解RemoteViews概念
- 《Android开发艺术探索》读书笔记 (5) 第5章 理解RemoteViews
- Android读书笔记---RemoteViews 远程View
- 理解Window和WindowManager————读书笔记
- Sizeof与Strlen的区别与联系
- IOS温故而知新(一) 一步一步分析新建App启动过程
- HTML5中Access-Control-Allow-Origin解决跨域问题
- Python 编码规范
- springMVC 与 struts+hibernate+spring优缺点(转)
- 理解RemoteViews————读书笔记
- 病毒木马查杀实战第017篇:U盘病毒之专杀工具的编写
- STL常用容器
- 根据某一分隔符分隔字符串
- PB之——DropDownListBox 与 DropDownPictureListBox
- 系统吞吐量、TPS(QPS)、用户并发量、性能测试概念和公式
- iOS-国家代码选择功能github开源分享
- Javascript
- sql注入问题