Chinaunix首页 | 论坛 | 博客
  • 博客访问: 278367
  • 博文数量: 91
  • 博客积分: 2105
  • 博客等级: 大尉
  • 技术积分: 1050
  • 用 户 组: 普通用户
  • 注册时间: 2009-09-14 19:30
文章分类
文章存档

2011年(11)

2010年(64)

2009年(16)

我的朋友

分类: LINUX

2011-06-09 19:33:40

最近封装一些功能性的jar包,因为需要产生一些动作,然后给调用者一些回调,所以用到了事件和监听器。 

    举个例子,比如DragListener和DragEvent,最开始写的时候,每次Drag动作都触发一个DragEvent事件,然后就得new一个DragEvent对象。后来感觉这样太浪费内存了,然后就研究了一下系统的MotionEvent这个类,找到了好的 解决方案。


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

 

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

Java代码  收藏代码
  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方法:

Java代码  收藏代码
  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方法如下:

Java代码  收藏代码
  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.     }  

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

阅读(757) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~