最近封装一些功能性的jar包,因为需要产生一些动作,然后给调用者一些回调,所以用到了事件和监听器。
举个例子,比如DragListener和DragEvent,最开始写的时候,每次Drag动作都触发一个DragEvent事件,然后就得new一个DragEvent对象。后来感觉这样太浪费内存了,然后就研究了一下系统的MotionEvent这个类,找到了好的 解决方案。
MotionEvent的构造方法是匿名的,不能直接创建,对外提供的获取对象的接口是静态的obtain方法,可以从一个MotionEvent对象获取,也可以从一些变量获取。为什么说它是个好的解决方案呢,因为它提供了一个recycle方法 ,可以将当前的对象回收,下次要用的时候就不用重新再new一个新的对象了,直接从它的回收池里面拿就行。
下面讲解一下,MotionEvent里面有几个比较重要的变量,如下 :
-
- private MotionEvent mNext;
- private boolean mRecycled;
-
- static private final int MAX_RECYCLED = 10;
- static private Object gRecyclerLock = new Object();
- static private int gRecyclerUsed = 0;
- static private MotionEvent gRecyclerTop = null;
然后有一个静态的obtain方法:
- static private MotionEvent obtain() {
- synchronized (gRecyclerLock) {
- if (gRecyclerTop == null) {
- return new MotionEvent();
- }
- MotionEvent ev = gRecyclerTop;
- gRecyclerTop = ev.mNext;
- gRecyclerUsed--;
- ev.mRecycledLocation = null;
- ev.mRecycled = false;
- return ev;
- }
- }
其它几个obtain方法都首先调用obtain()方法从回收栈中获取对象,然后赋值。
它的recycle方法如下:
- public void recycle() {
-
- if (TRACK_RECYCLED_LOCATION) {
- if (mRecycledLocation != null) {
- throw new RuntimeException(toString() + " recycled twice!", mRecycledLocation);
- }
- mRecycledLocation = new RuntimeException("Last recycled here");
- } else if (mRecycled) {
- throw new RuntimeException(toString() + " recycled twice!");
- }
-
- synchronized (gRecyclerLock) {
- if (gRecyclerUsed < MAX_RECYCLED) {
- gRecyclerUsed++;
- mNumHistory = 0;
-
- mNext = gRecyclerTop;
- gRecyclerTop = this;
- }
- }
- }
根据这个思路,我也做了一个Event,同样的回收原理,使得事件触发频繁的时候,大大的节约了内存的使用。
阅读(719) | 评论(0) | 转发(0) |