*概述
---SWT中创建的与操作系统相关的资源需要手动释放,如Image,Font,GC等,从api的角度看,就是org.eclipse.swt.graphics.Resource的所有子类.
所以对于需要重复利用的资源,我们一般做法是定义一个Map管理这些资源,最后再释放,如下面的做法
ColorManager示例 /* * Copyright(C) 2010 Agree Tech, All rights reserved. * * Created on 2010-9-7 by dzh */ package cn.com.agree.modeling; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.widgets.Display; public class ColorManager { private final Map<RGB,Color> colorMap =new HashMap<RGB,Color>(); public Color getColor(RGB rgb){ Color color =(Color) colorMap.get(rgb); if(color==null){ color =new Color(Display.getDefault(),rgb); colorMap.put(rgb, color); } return color; } public void dispose(){ Iterator<Color> i =colorMap.values().iterator(); while(i.hasNext()){ i.next().dispose(); } colorMap.clear(); } }
---还有另外一种方式,利用SWT的特性:每个SWT程序,都有一个Display对象,Display在UI开始时被创建,在程序结束时被释放,咱们看看Display提供了些什么.
*实现原理
---display释放调用过程分析
Device.dispose()->Display.release()->Display.disposeList执行,
Display片段/* Display Shutdown */ Runnable [] disposeList;//这是Display定义的一个数组 protected void release () { sendEvent (SWT.Dispose, new Event ()); Shell [] shells = getShells (); for (int i=0; i<shells.length; i++) { Shell shell = shells [i]; if (!shell.isDisposed ()) shell.dispose (); } if (tray != null) tray.dispose (); tray = null; if (taskBar != null) taskBar.dispose (); taskBar = null; while (readAndDispatch ()) {} if (disposeList != null) { for (int i=0; i<disposeList.length; i++) { //执行disposeList内容 if (disposeList [i] != null) disposeList [i].run (); } } disposeList = null; synchronizer.releaseSynchronizer (); synchronizer = null; releaseDisplay (); super.release (); }
---现在知道了,只要给数组添加java.lang.Runnable,在Runnable.run()实现资源释放,这样就实现了我们缓存和自动释放的目的.
添加Runnable/** * Causes the <code>run()</code> method of the runnable to * be invoked by the user-interface thread just before the * receiver is disposed. Specifying a <code>null</code> runnable * is ignored. * * @param runnable code to run at dispose time. * * @exception SWTException <ul> * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li> * </ul> */ public void disposeExec (Runnable runnable) { //添加runnable checkDevice (); if (disposeList == null) disposeList = new Runnable [4]; for (int i=0; i<disposeList.length; i++) { if (disposeList [i] == null) { disposeList [i] = runnable; return; } } Runnable [] newDisposeList = new Runnable [disposeList.length + 4]; System.arraycopy (disposeList, 0, newDisposeList, 0, disposeList.length); newDisposeList [disposeList.length] = runnable; disposeList = newDisposeList; }
*示例分析
---jface根据上面介绍的原理,在org.eclipse.jface.resource下提供了对需要释放资源的缓存类
---以org.eclipse.jface.resource.ColorRegistry为例,看看实现方式
ColorRegistry示例 /** * Collection of <code>Color</code> that are now stale to be disposed when * it is safe to do so (i.e. on shutdown). */ private List staleColors = new ArrayList(); //缓存资源 /** * Table of known colors, keyed by symbolic color name (key type: <code>String</code>, * value type: <code>org.eclipse.swt.graphics.Color</code>. */ private Map stringToColor = new HashMap(7); /** * Runnable that cleans up the manager on disposal of the display. */ //定义Runnable protected Runnable displayRunnable = new Runnable() { public void run() { clearCaches(); //释放资源 } }; public ColorRegistry(Display display, boolean cleanOnDisplayDisposal) { Assert.isNotNull(display); this.display = display; this.cleanOnDisplayDisposal = cleanOnDisplayDisposal; if (cleanOnDisplayDisposal) { hookDisplayDispose(); //将runnable添加到Display释放数组中 } } /** * Hook a dispose listener on the SWT display. */ private void hookDisplayDispose() { display.disposeExec(displayRunnable); }
*总结
---由于资源创建过多,没有及时释放,或者遗漏需要释放的资源,会导致"no more handlers"异常,以致程序崩溃.
所以缓存能提升性能,避免忘记释放,但是要注意在恰当的时候就及时释放.
本文详细介绍了SWT中创建的与操作系统相关的资源需要手动释放,并提供了使用Map管理资源和自动释放的方法。通过实现原理分析,展示了如何利用SWT特性在程序结束时自动释放资源。以ColorRegistry为例,说明了在组织资源缓存与自动释放过程中的应用。强调了资源及时释放的重要性,以避免程序崩溃。
760

被折叠的 条评论
为什么被折叠?



