首页 文章 精选 留言 我的

精选列表

搜索[记忆机制],共10000篇文章
优秀的个人博客,低调大师

中间件-几种常见的消息机制

Kafka与RabbitMQ、RocketMQ的定义 Kafka是LinkedIn开源的分布式发布-订阅消息系统,目前归属于Apache定级项目。Kafka主要特点是基于Pull的模式来处理消息消费,追求高吞吐量,一开始的目的就是用于日志收集和传输。0.8版本开始支持复制,不支持事务,对消息的重复、丢失、错误没有严格要求,适合产生大量数据的互联网服务的数据收集业务。 RabbitMQ是使用Erlang语言开发的开源消息队列系统,基于AMQP协议来实现。AMQP的主要特征是面向消息、队列、路由(包括点对点和发布/订阅)、可靠性、安全。AMQP协议更多用在企业系统内,对数据一致性、稳定性和可靠性要求很高的场景,对性能和吞吐量的要求还在其次。 RocketMQ是阿里开源的消息中间件,它是纯Java开发,具有高吞吐量、高可用性、适合大规模分布式系统应用的特点。RocketMQ思路起源于Kafka,但并不是Kafka的一个Copy,它对消息的可靠传输及事务性做了优化,目前在阿里集团被广泛应用于交易、充值、流计算、消息推送、日志流式处理、binglog分发等场景。

优秀的个人博客,低调大师

android的窗口机制分析------UI管理系统

Activity可以看做是整个Android系统的人机接口,它提供了一个窗口来绘制UI,每个Activity在启动时,我们都需要给它设置一个Content view,作为Activity所呈现的UI内容,这个过程是通过setContentView()方法来实现的。 众所周知,android系统中强化了view的概念,主要是体现在对view的管理上,Android中的view以2种形态存在,单一的View和多个View组成的ViewGroup。Content view是以ViewGroup的形式存在的,也就是说在一个Activity窗口中可以添加多个View,这样就实现了Android窗口系统的UI多样化。activity启动时给activity窗口设置的Content view 是从xml文件中解析出来的,那么android是怎么样对这个ContentView进行管理的呢,它的内部实现逻辑又是怎样的呢? 在进行分析之前,首先给出一个Activity的window和view系统的层级关系,这个层级关系就是在Activity设置完ContentView之后的状况。 如下图。 下面来一一介绍各个层级的含义与作用 1.1PhoneWindow PhoneWindow是Android中的最基本的窗口系统,每个Activity 均会创建一个PhoneWindow对象,是Activity和整个View系统交互的接口。 1.2DecorView DecorView是当前Activity所有View的祖先,它并不会向用户呈现任何东西,它主要有如下几个功能,可能不全: A. Dispatch ViewRoot分发来的key、touch、trackball等外部事件; B. DecorView有一个直接的子View,我们称之为System Layout,这个View是从系统的Layout.xml中解析出的,它包含当前UI的风格,如是否带title、是否带process bar等。可以称这些属性为Window decorations。 C. 作为PhoneWindow与ViewRoot之间的桥梁,ViewRoot通过DecorView设置窗口属性。 1.3System Layout 目前android根据用户需求预设了几种UI 风格,通过PhoneWindow通过解析预置的layout.xml来获得包含有不同Window decorations的layout,我们称之为System Layout,我们将这个System Layout添加到DecorView中,目前android提供了8种System Layout,如下图。 预设风格可以通过PhoneWindow方法requestFeature()来设置,需要注意的是这个方法需要在setContentView()方法调用之前调用。 1.4Content Parent Content Parent这个ViewGroup对象才是真真正正的ContentView的parent,我们的ContentView终于找到了寄主,它其实对应的是System Layout中的id为”content”的一个FrameLayout。这个FrameLayout对象包括的才是我们的Activity的layout(每个System Layout都会有这么一个id为”content”的一个FrameLayout)。 1.5Activity Layout 这个ActivityLayout便是我们需要向窗口设置的ContentView,现在我们发现其实它的地位很低,同时这一部分才是和user交互的UI部分,其上的几层并不能响应并完成user输入所期望达到的目的。 本文转自 一点点征服 博客园博客,原文链接:http://www.cnblogs.com/ldq2016/p/6671951.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

Android事件分发机制源码和实例解析

1.事件分发过程的理解 1.1. 概述 1.2. 主要方法 1.3. 核心行为 1.4. 特殊情况 2.案例分析 2.1. 案例1:均不消费 down 事件 2.2. 案例2:View0 消费 down 事件 2.3. 案例3:ViewGroup2nd 消费 down 事件 3.down 事件分发图 1. 事件分发过程的理解 1.1. 概述 事件主要有 down(MotionEvent.ACTION_DOWN),move(MotionEvent.ACTION_MOVE),up(MotionEvent.ACTION_UP)。 基本上的手势均由 down 事件为起点,up 事件为终点,中间可能会有一定数量的move 事件。这三种事件是大部分手势动作的基础。 事件和相关信息(比如坐标)封装成 MotionEvent。 大体的分发过程为:首先传递到 Activity,然后传给了 Activity 依附的 Window,接着由 Window 传给视图的顶层 View 也就是 DecorView,最后由 DecorView 向整个 ViewTree 分发。分发还会有回溯的过程。最后还会回到 Activity 的调用中。 Activity 的分发事件源码 publicbooleandispatchTouchEvent(MotionEventev){if(ev.getAction()==MotionEvent.ACTION_DOWN){ onUserInteraction(); }if(getWindow().superDispatchTouchEvent(ev)){returntrue; }returnonTouchEvent(ev); } 在 getWindow().superDispathTouchEvent 就是用来分发事件到 DecorView 中。如果整个 ViewTree 没有消费事件,会调用 Activity 的 onTouchEvent。 1.2. 主要方法 1.2.1. 概览 主要涉及到的 View 或 ViewGroup 的方法有: dispatchTouchEvent,该方法封装了事件分发的整个过程。是事件分发的 调度者 和 指挥官 。的核心过程均在该方法中。下面的 onInterceptTouchEvent 和 onTouchEvent 的回调的调用就在该方法体中。是否传递事件到 onInterceptTouchEvent 和 onTouchEvent 由 dispatchTouchEvent 决定。 onInterceptTouchEvent,该方法决定了是否拦截事件。只有 ViewGroup 有该回调。返回 true 表示拦截,返回 false 表示不拦截。自定义 View 的时候,可以重载该方法,通过一些特定的逻辑来决定是否拦截事件。如果拦截,接下来会调用该 ViewGroup 的 onTouchEvent 来处理事件。 onTouchEvent,该方法处理了事件,并决定是否继续消费后续事件。该方法调用的前置条件: 该 View 拦截了事件 子 View 都不消费事件 没有子 View 该方法正式处理 MotionEvent。返回 true 表示消费,返回 false 不消费。如果消费,接下来的事件还会传递到该 View 的 dispatchTouchEvent 中;如果不消费,后面的事件不会再传过来。 onTouchListener 的 onTouch 回调,和 onTouchEvent 一样,优先级比 onTouchEvent 高,如果有设置该监听,并且 onTouch 返回 true,就不会再调用 onTouchEvent 了。如果返回 false,事件还是会传递到 onTouchEvent 中。 1.2.2. dispatchTouchEvent 方法中的一些细节处理: 大部分手势的起点为 down 事件,dispatchTouchEvent 如果收到 down 事件,会重新设置一些变量和标记 重置变量和标记的源码 //Handleaninitialdown.if(actionMasked==MotionEvent.ACTION_DOWN){//Throwawayallpreviousstatewhenstartinganewtouchgesture. //Theframeworkmayhavedroppedtheuporcanceleventforthepreviousgesture //duetoanappswitch,ANR,orsomeotherstatechange. cancelAndClearTouchTargets(ev); resetTouchState(); } 实际的源码中,ViewGroup 继承于 View。 当子 View 不消费事件或者 ViewGroup 拦截了事件会传空值到 dispatchTransformedTouchEvent 中,内部会调用 super.dispatchTouchEvent,最终把事件传给 onTouchEvent 进行处理。 dispatchTransformedTouchEvent 关键部分 //Performanynecessarytransformationsanddispatch.if(child==null){ handled=super.dispatchTouchEvent(transformedEvent); }else{finalfloatoffsetX=mScrollX-child.mLeft;finalfloatoffsetY=mScrollY-child.mTop; transformedEvent.offsetLocation(offsetX,offsetY);if(!child.hasIdentityMatrix()){ transformedEvent.transform(child.getInverseMatrix()); } handled=child.dispatchTouchEvent(transformedEvent); } 也就是 dispatchTransformTouchEvent 完成了分发的最后过程: a. 传入的 child 不为空,转化坐标为 child 的坐标系,调用 child.dispatchTouchEvent向 child 分发事件 b. 传入的 child 为空,调用 super.dispatchTouchEvent 分发事件到 onTouchEvent 中 1.2.3 方法的主要关系 对于一个 ViewGroup 来说,几个重要方法的关系如下 几个重要方法关系伪代码 publicbooleandispatchTouchEvent(MotionEvente){booleanconsumed=false;if(onInterceptTouchEvent(e)){ consumed=onTouchEvent(e); }else{for(Viewview:childs){ consumed=view.dispatchTouchEvent(e);if(consumed){break; } }if(!consumed){ consumed=onTouchEvent(e); } } returnconsumed; } 这是事件分发过程的简单描述,具体远比这复杂的多。 1.3. 核心行为 View 或 ViewGroup 有两个核心的行为:拦截(intercept) 和 消费(consume)。这两者是相互独立的,拦截不一定消费。是否要拦截看 onIntercepTouchEvent。是否要消费看 onTouchEvent。 注意:是否拦截还有其他因素影响。如果不是 down 事件,并且 mFirstTouchTarget 为空值,就会直接拦截事件。 在 dispatchTouchEvent 中有这样的代码 拦截的关键源码 //Checkforinterception.finalbooleanintercepted;if(actionMasked==MotionEvent.ACTION_DOWN ||mFirstTouchTarget!=null){finalbooleandisallowIntercept=(mGroupFlags&FLAG_DISALLOW_INTERCEPT)!=0;if(!disallowIntercept){ intercepted=onInterceptTouchEvent(ev); ev.setAction(action);//restoreactionincaseitwaschanged }else{ intercepted=false; } }else{//Therearenotouchtargetsandthisactionisnotaninitialdown //sothisviewgroupcontinuestointercepttouches. intercepted=true; } 从上面的源码可以看出,在不是 down 事件,并且 mFirstTouchTarget 为空的情况下,不会走 onInterceptTouchEvent 而是直接拦截。如果满足了,还会看 FLAG_DISALLOW_INTERCEPT 标记,如果不允许拦截(disallowIntercept 为 true),也不会走onInterceptTouchEvent,直接标记不拦截。 处理调用 onTouchEvent 的源码 booleanresult=false; ... ListenerInfoli=mListenerInfo;if(li!=null&&li.mOnTouchListener!=null &&(mViewFlags&ENABLED_MASK)==ENABLED &&li.mOnTouchListener.onTouch(this,event)){ result=true; }if(!result&&onTouchEvent(event)){ result=true; } 可以看出,在该 View 为 ENABLE 的状态并且有 mTouchListener,会先调用 onTouch。在onTouch 返回 false 时才会继续调用 onTouchEvent。 onTouch 或者 onTouchEvent 的处理结果有: 返回 true,会继续消费后续事件。意味着,后面的事件将会继续传递到该 View 的 dispatchTouchEvent 方法中进行调度。父 View 会为该 View 创建一个 TouchTarget 实例加入链表中,链表的第一项为 mFirstTouchTarget。后续的 move 和 up 事件会直接交给该 View 的 dispatchTouchEvent。 返回 false,不再消费后续事件。意味着,后面的事件将会被父 View 拦截,而不再传递下来。 1.4. 特殊情况 比较特殊的情况有,子 View 可以使用 requestDisallowInterceptTouchEvent 影响去父 View 的分发,可以决定父 View 是否要调用 onInterceptTouchEvent 。比如,requestDisallowInterceptTouchEvent(true),父 View 就不用调用 onInterceptTouchEvent 来判断拦截,而就是不拦截。 该方法可以用来解决手势冲突。比如子 View 先消费了事件,但是后面父 View 也满足了手势触发的条件而拦截事件,导致子 View 手势执行一半后无法继续响应。可以使用 requestDisallowInterceptTouchEvent(true),这样后面的事件,父 View 不会走 onInterceptTouchEvent 回调来判断是否要拦截事件,而是直接把事件继续传下来。 2. 案例分析 下面举三个简单的例子,三个类 ViewGroup1st,ViewGroup2nd 和 View0,层级关系为 <ViewGroup1st> <ViewGroup2nd> <View0/> </ViewGroup2nd></ViewGroup1st> 这三个类有两层 ViewGroup,最底层为 View,这几个例子主要理解 消费 行为,所以不做事件的拦截。 2.1. 案例1:均不消费 down 事件 在触摸屏幕中 View0 的区域后,输出 log 信息如下 12-3014:06:03.69431323-31323/lyn.demoD/ViewGroup1st:dispatchTouchEventbefore12-3014:06:03.69431323-31323/lyn.demoD/ViewGroup1st:onInterceptTouchEventreturn:false12-3014:06:03.69431323-31323/lyn.demoD/ViewGroup2nd:dispatchTouchEventbefore12-3014:06:03.69431323-31323/lyn.demoD/ViewGroup2nd:onInterceptTouchEventreturn:false12-3014:06:03.69431323-31323/lyn.demoD/View0:dispatchTouchEventbefore12-3014:06:03.69431323-31323/lyn.demoD/View0:onTouchEventreturn:false12-3014:06:03.69431323-31323/lyn.demoD/View0:dispatchTouchEventreturn:false12-3014:06:03.69431323-31323/lyn.demoD/ViewGroup2nd:onTouchEventreturn:false12-3014:06:03.69431323-31323/lyn.demoD/ViewGroup2nd:dispatchTouchEventreturn:false12-3014:06:03.69431323-31323/lyn.demoD/ViewGroup1st:onTouchEventreturn:false12-3014:06:03.69431323-31323/lyn.demoD/ViewGroup1st:dispatchTouchEventreturn:false 当 down 事件从 DecorView 开始了分发过程: ViewGroup1st 收到事件,执行 onInterceptTouchEvent 返回 false,不拦截,于是调用 ViewGroup2nd 的 dispatchTouchEvent 向 ViewGroup2nd分发。 ViewGroup2nd 收到事件,dispatchTouchEvent 重复 ViewGroup1st 的分发策略。因为都不拦截,所以调用了 View0 的 dispatchTouchEvent。 View0 收到事件,而 View0 不是 ViewGroup 类型,所以把事件直接交给了 onTouchEvent。 View0 不消费事件,onTouchEvent 返回 false,dispatchTouchEvent 方法因此也返回 false。 ViewGroup2nd 因为 View0 的 dispatchTouchEvent 返回 false,确定了子类不消费事件,于是把事件传递给 onTouchEvent。但本身也不消费事件,所以 onTouchEvent 也返回 false,继续把事件上抛到 ViewGroup1st。 ViewGroup1st 重复了 ViewGroup2nd 的过程。 随后,move 事件不会再往下传了,而是直接被 Activity 拦截。 2.2. 案例2:View0 消费 down 事件 首先是 down 事件的传递,log 如下 12-3014:14:09.3847350-7350/lyn.demoD/ViewGroup1st:dispatchTouchEventbefore12-3014:14:09.3847350-7350/lyn.demoD/ViewGroup1st:onInterceptTouchEventreturn:false12-3014:14:09.3847350-7350/lyn.demoD/ViewGroup2nd:dispatchTouchEventbefore12-3014:14:09.3847350-7350/lyn.demoD/ViewGroup2nd:onInterceptTouchEventreturn:false12-3014:14:09.3847350-7350/lyn.demoD/View0:dispatchTouchEventbefore12-3014:14:09.3847350-7350/lyn.demoD/View0:onTouchEventreturn:true12-3014:14:09.3847350-7350/lyn.demoD/View0:dispatchTouchEventreturn:true12-3014:14:09.3847350-7350/lyn.demoD/ViewGroup2nd:dispatchTouchEventreturn:true12-3014:14:09.3847350-7350/lyn.demoD/ViewGroup1st:dispatchTouchEventreturn:true ViewGroup1st 和 ViewGroup2st 的传递和案例1一样。区别在于 View0 onTouchEvent 返回 true 消费后续事件后,View0 的 dispatchTouchEvent 也返回 true,ViewGroup2nd 和 ViewGroup1st 不执行 onTouchEvent 也直接返回 true 然后稍微移动一下手指,move 事件往下传递 12-3014:14:09.4847350-7350/lyn.demoD/ViewGroup1st:dispatchTouchEventbefore12-3014:14:09.4847350-7350/lyn.demoD/ViewGroup1st:onInterceptTouchEventreturn:false12-3014:14:09.4847350-7350/lyn.demoD/ViewGroup2nd:dispatchTouchEventbefore12-3014:14:09.4847350-7350/lyn.demoD/ViewGroup2nd:onInterceptTouchEventreturn:false12-3014:14:09.4847350-7350/lyn.demoD/View0:dispatchTouchEventbefore12-3014:14:09.4847350-7350/lyn.demoD/View0:onTouchEventreturn:true12-3014:14:09.4847350-7350/lyn.demoD/View0:dispatchTouchEventreturn:true12-3014:14:09.4847350-7350/lyn.demoD/ViewGroup2nd:dispatchTouchEventreturn:true12-3014:14:09.4847350-7350/lyn.demoD/ViewGroup1st:dispatchTouchEventreturn:true 过程和 down 事件的传递一样。因为同样会经过 ViewGroup2nd 的 onInterceptTouchEvent,如果这时候 ViewGroup2nd 有拦截行为,move 事件就不会传到 View0 了。要避免这种情况发生,需要调用 View0 的requestDisallowInterceptTouchEvent,可见 1.4 部分。 2.3. 案例3:ViewGroup2nd 消费 down 事件 首先是 down 事件的传递,log 如下 12-3014:25:30.07418848-18848/lyn.demoD/ViewGroup1st:dispatchTouchEventbefore12-3014:25:30.07418848-18848/lyn.demoD/ViewGroup1st:onInterceptTouchEventreturn:false12-3014:25:30.08418848-18848/lyn.demoD/ViewGroup2nd:dispatchTouchEventbefore12-3014:25:30.08418848-18848/lyn.demoD/ViewGroup2nd:onInterceptTouchEventreturn:false12-3014:25:30.08418848-18848/lyn.demoD/View0:dispatchTouchEventbefore12-3014:25:30.08418848-18848/lyn.demoD/View0:onTouchEventreturn:false12-3014:25:30.08418848-18848/lyn.demoD/View0:dispatchTouchEventreturn:false12-3014:25:30.08418848-18848/lyn.demoD/ViewGroup2nd:onTouchEventreturn:true12-3014:25:30.08418848-18848/lyn.demoD/ViewGroup2nd:dispatchTouchEventreturn:true12-3014:25:30.08418848-18848/lyn.demoD/ViewGroup1st:dispatchTouchEventreturn:true 由于 View0 不消费事件,dispatchTouchEvent 返回 false,所以执行了 ViewGroup2nd 的 onTouchEvent 方法。 ViewGroup2nd 消费事件,onTouchEvent 返回 true,之后 ViewGroup2nd 和 ViewGroup1st 的 dispatchTouchEvent 均返回 true。 动一下手指,move 事件接着传 2-3014:25:30.17418848-18848/lyn.demoD/ViewGroup1st:dispatchTouchEventbefore12-3014:25:30.17418848-18848/lyn.demoD/ViewGroup1st:onInterceptTouchEventreturn:false12-3014:25:30.17418848-18848/lyn.demoD/ViewGroup2nd:dispatchTouchEventbefore12-3014:25:30.17418848-18848/lyn.demoD/ViewGroup2nd:onTouchEventreturn:true12-3014:25:30.17418848-18848/lyn.demoD/ViewGroup2nd:dispatchTouchEventreturn:true12-3014:25:30.17418848-18848/lyn.demoD/ViewGroup1st:dispatchTouchEventreturn:true 这时候,ViewGroup2nd 直接拦截了 move 事件,不再经过 onInterceptTouchEvent,也不再向 View0 分发,而是直接调用 onTouchEvent 进行处理。 3. down 事件分发图 在每个 View 都不拦截 down 事件的情况下,down 事件是这样传递的 本文作者:佚名 来源:51CTO

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册