Android系统事件的recycle原理

54 篇文章 0 订阅
22 篇文章 0 订阅

From: http://www.cnblogs.com/jk1001/archive/2010/07/25/1784837.html

最近封装一些功能性的jar包,因为需要产生一些动作,然后给调用者一些回调,所以用到了事件和监听器。 
举个例子,比如DragListener和DragEvent,最开始写的时候,每次Drag动作都触发一个DragEvent事件,然后就得new一个DragEvent对象。后来感觉这样太浪费内存了,然后就研究了一下系统的MotionEvent这个类,找到了好的 解决方案。

MotionEvent的构造方法是匿名的,不能直接创建,对外提供的获取对象的接口是静态的obtain方法,可以从一个MotionEvent对象获取,也可以从一些变量获取。为什么说它是个好的解决方案呢,因为它提供了一个recycle方法 ,可以将当前的对象回收,下次要用的时候就不用重新再new一个新的对象了,直接从它的回收池里面拿就行。

下面讲解一下,MotionEvent里面有几个比较重要的变量,如下

 

复制代码
    
    
1 // 变量 2   private MotionEvent mNext; // 指向回收栈的下一个对象 3   private boolean mRecycled; // 标志是否是被回收掉的对象 4   // 静态变量 5 static private final int MAX_RECYCLED = 10 ; // 最大可回收的数目 6 static private Object gRecyclerLock = new Object(); // 锁定整个类用的 7 static private int gRecyclerUsed = 0 ; // 回收栈中回收的对象数目 8 static private MotionEvent gRecyclerTop = null ; // 回收栈的栈顶对象
复制代码

 

    然后有一个静态的obtain方法:

  其它几个obtain方法都首先调用obtain()方法从回收栈中获取对象,然后赋值。

      它的recycle方法如下:

复制代码
    
    
1 static private MotionEvent obtain() { 2 synchronized (gRecyclerLock) { // 锁住整个类 3 if (gRecyclerTop == null ) { // 栈顶不存在,就new一个新的 4 return new MotionEvent(); 5 } 6 MotionEvent ev = gRecyclerTop; // 栈顶存在,就用一个引用ev指向它 7 gRecyclerTop = ev.mNext; // 然后把栈顶的下一个对象提到栈顶 8 gRecyclerUsed -- ; // 回收栈中的对象数目减少一个 9 ev.mRecycledLocation = null ; // 是一个异常,作用未知 10 ev.mRecycled = false ; // 当前对象标志为未回收状态 11 return ev; 12 } 13 }
复制代码

  其它几个obtain方法都首先调用obtain()方法从回收栈中获取对象,然后赋值。

      它的recycle方法如下:

复制代码
    
    
1 public void recycle() { 2 // 确保recycle方法只调用一次 3 if (TRACK_RECYCLED_LOCATION) { 4 if (mRecycledLocation != null ) { 5 throw new RuntimeException(toString() + " recycled twice! " , mRecycledLocation); 6 } 7 mRecycledLocation = new RuntimeException( " Last recycled here " ); 8 } else if (mRecycled) { 9 throw new RuntimeException(toString() + " recycled twice! " ); 10 } 11 12 synchronized (gRecyclerLock) { // 锁住类 13 if (gRecyclerUsed < MAX_RECYCLED) { // 如果回收栈中的对象还没达到最大值 14 gRecyclerUsed ++ ; // 回收栈中元素数目增加1 15 mNumHistory = 0 ; 16 // 这两句是把当前对象的next指向以前的栈顶,然后把当前对象放到栈顶 17 mNext = gRecyclerTop; 18 gRecyclerTop = this ; 19 } 20 } 21 } 22
复制代码

根据这个思路,我也做了一个Event,同样的回收原理,使得事件触发频繁的时候,大大的节约了内存的使用


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值